|
danderson@91
|
1 |
/* vim: set ts=4 sw=4 tw=99 et: |
|
danderson@91
|
2 |
* |
|
dvander@60
|
3 |
* Copyright (C) 2004-2012 David Anderson |
|
dvander@60
|
4 |
* |
|
dvander@60
|
5 |
* This file is part of SourcePawn. |
|
dvander@60
|
6 |
* |
|
dvander@60
|
7 |
* SourcePawn is free software: you can redistribute it and/or modify it under |
|
dvander@60
|
8 |
* the terms of the GNU General Public License as published by the Free |
|
dvander@60
|
9 |
* Software Foundation, either version 3 of the License, or (at your option) |
|
dvander@60
|
10 |
* any later version. |
|
dvander@60
|
11 |
* |
|
dvander@60
|
12 |
* SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY |
|
dvander@60
|
13 |
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
dvander@60
|
14 |
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
|
dvander@60
|
15 |
* |
|
dvander@60
|
16 |
* You should have received a copy of the GNU General Public License along with |
|
dvander@60
|
17 |
* SourcePawn. If not, see http://www.gnu.org/licenses/. |
|
dvander@60
|
18 |
*/ |
|
danderson@96
|
19 |
#ifndef _include_sourcepawn2_api_h_ |
|
danderson@96
|
20 |
#define _include_sourcepawn2_api_h_ |
|
dvander@60
|
21 |
|
|
dvander@65
|
22 |
#include <assert.h> |
|
dvander@60
|
23 |
#include <stddef.h> |
|
dvander@64
|
24 |
#include "../include/keima_util.h" |
|
dvander@60
|
25 |
|
|
dvander@60
|
26 |
namespace ke { |
|
dvander@60
|
27 |
|
|
dvander@60
|
28 |
class Zone; |
|
dvander@60
|
29 |
class Object; |
|
dvander@60
|
30 |
class HandleScope; |
|
dvander@60
|
31 |
class HeapRoot; |
|
dvander@60
|
32 |
|
|
dvander@60
|
33 |
} |
|
dvander@60
|
34 |
|
|
dvander@60
|
35 |
namespace Ke { |
|
dvander@60
|
36 |
|
|
dvander@64
|
37 |
class Function; |
|
dvander@251
|
38 |
class Package; |
|
dvander@64
|
39 |
|
|
dvander@60
|
40 |
/* |
|
dvander@60
|
41 |
* A Handle is a safe pointer that holds an object reference, such that it |
|
dvander@60
|
42 |
* can be scanned and potentially moved by the garbage collector. |
|
dvander@60
|
43 |
*/ |
|
dvander@60
|
44 |
template <typename T> |
|
dvander@60
|
45 |
class Handle |
|
dvander@60
|
46 |
{ |
|
dvander@195
|
47 |
template <typename S> friend class Root; |
|
dvander@60
|
48 |
protected: |
|
dvander@60
|
49 |
template <typename S> void typeCheck() { |
|
dvander@60
|
50 |
while (false) { |
|
dvander@60
|
51 |
T *v1 = NULL; |
|
dvander@60
|
52 |
S *v2 = NULL; |
|
dvander@60
|
53 |
v1 = v2; |
|
dvander@60
|
54 |
(void)v1; |
|
dvander@60
|
55 |
} |
|
dvander@60
|
56 |
} |
|
dvander@60
|
57 |
|
|
dvander@60
|
58 |
public: |
|
dvander@60
|
59 |
Handle() |
|
dvander@60
|
60 |
: obj_(NULL) |
|
dvander@60
|
61 |
{ |
|
dvander@60
|
62 |
} |
|
dvander@60
|
63 |
|
|
dvander@60
|
64 |
template <typename S> Handle(Handle<S> other) |
|
dvander@60
|
65 |
: obj_(reinterpret_cast<S *>(*other)) |
|
dvander@60
|
66 |
{ |
|
dvander@60
|
67 |
typeCheck<S>(); |
|
dvander@60
|
68 |
} |
|
dvander@60
|
69 |
|
|
dvander@60
|
70 |
explicit Handle(T *obj) |
|
dvander@60
|
71 |
: obj_(obj) |
|
dvander@60
|
72 |
{ |
|
dvander@60
|
73 |
} |
|
dvander@60
|
74 |
|
|
dvander@60
|
75 |
T *operator ->() const { |
|
dvander@60
|
76 |
return obj_; |
|
dvander@60
|
77 |
} |
|
dvander@60
|
78 |
T *operator *() const { |
|
dvander@60
|
79 |
return obj_; |
|
dvander@60
|
80 |
} |
|
dvander@60
|
81 |
operator bool () const { |
|
dvander@60
|
82 |
return !!obj_; |
|
dvander@60
|
83 |
} |
|
dvander@60
|
84 |
|
|
dvander@65
|
85 |
protected: |
|
dvander@60
|
86 |
T *obj_; |
|
dvander@60
|
87 |
}; |
|
dvander@60
|
88 |
|
|
dvander@60
|
89 |
/* |
|
dvander@60
|
90 |
* A local variable that roots an object. Locals are owned by the nearest |
|
dvander@60
|
91 |
* HandleScope, and as soon as that HandleScope dies, all its Locals are |
|
dvander@60
|
92 |
* no longer available. |
|
dvander@60
|
93 |
*/ |
|
dvander@60
|
94 |
template <typename T> |
|
dvander@60
|
95 |
class Local : public Handle<T> |
|
dvander@60
|
96 |
{ |
|
dvander@60
|
97 |
public: |
|
dvander@60
|
98 |
Local() |
|
dvander@60
|
99 |
: Handle<T>() |
|
dvander@60
|
100 |
{ |
|
dvander@60
|
101 |
} |
|
dvander@60
|
102 |
|
|
dvander@60
|
103 |
template <typename S> Local(Local<S> other) |
|
dvander@60
|
104 |
: Handle<T>(reinterpret_cast<T *>(*other)) |
|
dvander@60
|
105 |
{ |
|
danderson@91
|
106 |
this->template typeCheck<S>(); |
|
dvander@60
|
107 |
} |
|
dvander@60
|
108 |
|
|
dvander@60
|
109 |
template <typename S> Local(S *other) |
|
dvander@60
|
110 |
: Handle<T>(other) |
|
dvander@60
|
111 |
{ |
|
dvander@60
|
112 |
} |
|
dvander@60
|
113 |
}; |
|
dvander@60
|
114 |
|
|
dvander@60
|
115 |
/* |
|
dvander@195
|
116 |
* A non-local variable that outlives HandleScopes. Unlike Local, a Root |
|
dvander@195
|
117 |
* actually represents a rooted location. Roots must be allocated and |
|
dvander@195
|
118 |
* disposed, and assignment to a root changes its contained object, not |
|
dvander@195
|
119 |
* the location of the object. |
|
dvander@60
|
120 |
*/ |
|
dvander@60
|
121 |
template <typename T> |
|
dvander@195
|
122 |
class Root |
|
dvander@60
|
123 |
{ |
|
dvander@60
|
124 |
public: |
|
dvander@195
|
125 |
Root() |
|
dvander@195
|
126 |
: root_(NULL) |
|
dvander@60
|
127 |
{ |
|
dvander@60
|
128 |
} |
|
dvander@60
|
129 |
|
|
dvander@195
|
130 |
Root(Handle<T> other) |
|
dvander@195
|
131 |
: root_(NULL) |
|
dvander@60
|
132 |
{ |
|
dvander@195
|
133 |
set(other); |
|
dvander@60
|
134 |
} |
|
dvander@60
|
135 |
|
|
dvander@195
|
136 |
inline ~Root(); |
|
dvander@195
|
137 |
|
|
dvander@195
|
138 |
operator const Handle<T>() const { |
|
dvander@195
|
139 |
return obj_; |
|
dvander@60
|
140 |
} |
|
dvander@60
|
141 |
|
|
dvander@195
|
142 |
bool operator ==(Handle<T> other) { |
|
dvander@195
|
143 |
return Handle<T>(*this) == other; |
|
dvander@60
|
144 |
} |
|
dvander@195
|
145 |
Root<T> &operator =(Handle<T> other) { |
|
dvander@195
|
146 |
set(other); |
|
dvander@60
|
147 |
return *this; |
|
dvander@60
|
148 |
} |
|
dvander@60
|
149 |
|
|
dvander@60
|
150 |
private: |
|
dvander@195
|
151 |
void set(Handle<T> other); |
|
dvander@195
|
152 |
|
|
dvander@195
|
153 |
ke::HeapRoot *root_; |
|
dvander@195
|
154 |
Handle<T> obj_; |
|
dvander@60
|
155 |
}; |
|
dvander@60
|
156 |
|
|
dvander@60
|
157 |
/* |
|
dvander@60
|
158 |
* A HandleScope is where Local roots are allcoated. When the HandleScope |
|
dvander@60
|
159 |
* is destroyed, all Handles created under it are also destroyed. HandleScopes |
|
dvander@60
|
160 |
* may only be allocated on the stack, in LIFO order. |
|
dvander@60
|
161 |
*/ |
|
dvander@60
|
162 |
class HandleScope |
|
dvander@60
|
163 |
{ |
|
dvander@60
|
164 |
protected: |
|
dvander@60
|
165 |
ke::Zone *zone_; |
|
dvander@60
|
166 |
ke::Object **position_; |
|
dvander@60
|
167 |
HandleScope *prev_; |
|
dvander@60
|
168 |
|
|
dvander@60
|
169 |
HandleScope(ke::Zone *zone, ke::Object **position, HandleScope *prev) |
|
dvander@60
|
170 |
: zone_(zone), |
|
dvander@60
|
171 |
position_(position), |
|
dvander@60
|
172 |
prev_(prev) |
|
dvander@60
|
173 |
{ |
|
dvander@60
|
174 |
} |
|
dvander@60
|
175 |
|
|
dvander@60
|
176 |
public: |
|
dvander@60
|
177 |
HandleScope(); |
|
dvander@60
|
178 |
~HandleScope(); |
|
dvander@60
|
179 |
|
|
dvander@60
|
180 |
static ke::Object **CreateHandle(ke::Object *obj); |
|
dvander@60
|
181 |
|
|
dvander@60
|
182 |
private: |
|
dvander@60
|
183 |
// Disallow silly stuff. |
|
dvander@60
|
184 |
HandleScope(const HandleScope &); |
|
dvander@60
|
185 |
void operator =(const HandleScope &); |
|
dvander@60
|
186 |
void *operator new (size_t size); |
|
dvander@60
|
187 |
void operator delete(void *, size_t); |
|
dvander@60
|
188 |
}; |
|
dvander@60
|
189 |
|
|
dvander@65
|
190 |
class Parameter; |
|
dvander@65
|
191 |
|
|
dvander@69
|
192 |
// Error messages are pumped through this interface. |
|
dvander@69
|
193 |
class IMessageReporter |
|
dvander@69
|
194 |
{ |
|
dvander@69
|
195 |
public: |
|
dvander@69
|
196 |
virtual void onOutOfMemory() { |
|
dvander@69
|
197 |
} |
|
dvander@69
|
198 |
virtual void onUncaughtException(const char *message) { |
|
dvander@69
|
199 |
} |
|
dvander@69
|
200 |
virtual void beginCompilationErrors(const char *file) { |
|
dvander@69
|
201 |
} |
|
dvander@69
|
202 |
virtual void reportCompilationError(const char *message, unsigned line, unsigned col) { |
|
dvander@69
|
203 |
} |
|
dvander@69
|
204 |
virtual void endCompilationErrors() { |
|
dvander@69
|
205 |
} |
|
dvander@69
|
206 |
}; |
|
dvander@69
|
207 |
|
|
dvander@69
|
208 |
// For the purposes of error reporting, very basic information can be queried |
|
dvander@69
|
209 |
// about the stack frame. This structure may be used to retrieve such |
|
dvander@69
|
210 |
// information. During iteration, it is illegal to re-enter any scripted code |
|
dvander@69
|
211 |
// or call any Keima functions that may cause garbage collection. |
|
dvander@69
|
212 |
class IStackFrameIterator |
|
dvander@69
|
213 |
{ |
|
dvander@69
|
214 |
public: |
|
dvander@195
|
215 |
virtual ~IStackFrameIterator() { |
|
dvander@195
|
216 |
} |
|
dvander@69
|
217 |
|
|
dvander@69
|
218 |
// Returns true if there are more frames, false otherwise. |
|
dvander@69
|
219 |
virtual bool done() = 0; |
|
dvander@69
|
220 |
|
|
dvander@69
|
221 |
// Returns the name of the current function. This may be NULL if the |
|
dvander@69
|
222 |
// function is anonymous. |
|
dvander@69
|
223 |
virtual const char *function() = 0; |
|
dvander@69
|
224 |
|
|
dvander@69
|
225 |
// Returns the file of the current function. This will return an invalid |
|
dvander@69
|
226 |
// path for C++ functions (for example, "<native>"). |
|
dvander@69
|
227 |
virtual const char *source() = 0; |
|
dvander@69
|
228 |
|
|
dvander@69
|
229 |
// Returns the line number currently executing on this frame. For C++ |
|
dvander@69
|
230 |
// functions, this is always 0. |
|
dvander@69
|
231 |
virtual unsigned lineNumber() = 0; |
|
dvander@69
|
232 |
|
|
dvander@69
|
233 |
// Advance to the previous frame in the call stack. |
|
dvander@69
|
234 |
virtual void prev() = 0; |
|
dvander@69
|
235 |
}; |
|
dvander@69
|
236 |
|
|
dvander@195
|
237 |
// Listener interface for when public functions are registered or unregisted. |
|
dvander@195
|
238 |
class IPublicFunctionListener |
|
dvander@195
|
239 |
{ |
|
dvander@195
|
240 |
public: |
|
dvander@195
|
241 |
virtual ~IPublicFunctionListener() { |
|
dvander@195
|
242 |
} |
|
dvander@195
|
243 |
|
|
dvander@195
|
244 |
// Called when a public function becomes available to the runtime. |
|
dvander@195
|
245 |
virtual void registerPublic(Handle<Function> fun) = 0; |
|
dvander@195
|
246 |
|
|
dvander@195
|
247 |
// Called when a public is no longer available to the runtime. |
|
dvander@195
|
248 |
virtual void unregisterPublic(Handle<Function> fun) = 0; |
|
dvander@195
|
249 |
}; |
|
dvander@195
|
250 |
|
|
dvander@64
|
251 |
// A string is an immutable UTF8 buffer. |
|
dvander@64
|
252 |
class KE_EXPORT String |
|
dvander@64
|
253 |
{ |
|
dvander@64
|
254 |
public: |
|
dvander@251
|
255 |
static Local<String> NewAscii(const char *str); |
|
dvander@251
|
256 |
|
|
dvander@64
|
257 |
// Returns the length of the string, in bytes. |
|
dvander@64
|
258 |
unsigned length(); |
|
dvander@64
|
259 |
|
|
dvander@64
|
260 |
// Returns the character buffer of the string, or NULL on failure. If the |
|
dvander@64
|
261 |
// string is interned, chars() is guaranteed to succeed. |
|
dvander@64
|
262 |
const char *chars(); |
|
dvander@64
|
263 |
}; |
|
dvander@64
|
264 |
|
|
dvander@64
|
265 |
// A function is an executable unit of code. |
|
dvander@64
|
266 |
class KE_EXPORT Function |
|
dvander@64
|
267 |
{ |
|
dvander@64
|
268 |
public: |
|
dvander@64
|
269 |
// Returns the name of a function, which may be NULL. If not NULL, the |
|
dvander@68
|
270 |
// string is guaranteed to be interned. |
|
dvander@64
|
271 |
Local<String> name(); |
|
dvander@251
|
272 |
|
|
dvander@251
|
273 |
// Returns the package the function was created in. |
|
dvander@251
|
274 |
Local<Package> package(); |
|
dvander@64
|
275 |
}; |
|
dvander@64
|
276 |
|
|
dvander@170
|
277 |
// A pubvar is an ISourcePawnEngine-compatible structure that holds information |
|
dvander@170
|
278 |
// about public variables. |
|
dvander@170
|
279 |
class KE_EXPORT Pubvar |
|
dvander@170
|
280 |
{ |
|
dvander@170
|
281 |
public: |
|
dvander@170
|
282 |
// Returns the name of a pubvar, which is never NULL. The string is |
|
dvander@170
|
283 |
// guaranteed to be interned. |
|
dvander@170
|
284 |
Local<String> name(); |
|
dvander@170
|
285 |
}; |
|
dvander@170
|
286 |
|
|
dvander@251
|
287 |
// A package is a collection of compiled files and possibly sub-packages. |
|
dvander@251
|
288 |
// Internally, packages are used to implement the "import" statement. However, |
|
dvander@251
|
289 |
// the host application can also create packages to organize related files, |
|
dvander@251
|
290 |
// restrict import visibility, or implement hot swapping of loaded modules. |
|
dvander@251
|
291 |
class KE_EXPORT Package |
|
dvander@62
|
292 |
{ |
|
dvander@62
|
293 |
public: |
|
dvander@251
|
294 |
enum { |
|
dvander@251
|
295 |
Normal = 0, |
|
dvander@251
|
296 |
|
|
dvander@251
|
297 |
// The package cannot be accessed from any import statement. |
|
dvander@251
|
298 |
Hidden = (1 << 0), |
|
dvander@251
|
299 |
|
|
dvander@251
|
300 |
// Source files compiled in this package cannot import names in the |
|
dvander@251
|
301 |
// package. |
|
dvander@251
|
302 |
Jailed = (1 << 1) |
|
dvander@251
|
303 |
}; |
|
dvander@251
|
304 |
|
|
dvander@251
|
305 |
// Creates a package. The parent package may be NULL. The name can be NULL |
|
dvander@251
|
306 |
// as well. |path| must be a filesystem path, which will be normalized |
|
dvander@251
|
307 |
// according to OS-specific rules. |
|
dvander@251
|
308 |
static Local<Package> New(Handle<Package> parent, |
|
dvander@251
|
309 |
Handle<String> name, |
|
dvander@251
|
310 |
const char *path, |
|
dvander@251
|
311 |
unsigned flags); |
|
dvander@251
|
312 |
|
|
dvander@251
|
313 |
// Returns the name of the package, which may be NULL. The string is |
|
dvander@251
|
314 |
// guaranteed to be interned. |
|
dvander@251
|
315 |
Local<String> name(); |
|
dvander@251
|
316 |
|
|
dvander@251
|
317 |
// Returns the full path of the package. The string is guaranteed to be |
|
dvander@251
|
318 |
// interned. |
|
dvander@251
|
319 |
Local<String> path(); |
|
dvander@251
|
320 |
|
|
dvander@251
|
321 |
// Sets the package's native identity. This is a host-application defined |
|
dvander@251
|
322 |
// value that is passed to native callbacks. Packages created under this |
|
dvander@251
|
323 |
// one will automatically inherit this native identity. |
|
dvander@251
|
324 |
void setNativeIdentity(void *identity); |
|
dvander@251
|
325 |
|
|
dvander@251
|
326 |
// Returns the package's native identity, or NULL if none was set. |
|
dvander@251
|
327 |
void *getNativeIdentity(); |
|
dvander@62
|
328 |
}; |
|
dvander@62
|
329 |
|
|
dvander@62
|
330 |
class Keima |
|
dvander@62
|
331 |
{ |
|
dvander@62
|
332 |
public: |
|
dvander@62
|
333 |
/* |
|
dvander@62
|
334 |
* Initializes the Keima engine. This must be called exactly once before any |
|
dvander@62
|
335 |
* other Keima functions are called. After this, it is safe to use Keima |
|
dvander@251
|
336 |
* on the calling thread only. It is not safe to race on calling this. |
|
dvander@62
|
337 |
*/ |
|
dvander@62
|
338 |
static bool Initialize(); |
|
dvander@60
|
339 |
|
|
dvander@62
|
340 |
/* |
|
dvander@62
|
341 |
* Shuts down the Keima engine and frees data structures on all threads. |
|
dvander@62
|
342 |
*/ |
|
dvander@62
|
343 |
static void Shutdown(); |
|
dvander@60
|
344 |
|
|
dvander@62
|
345 |
/* |
|
dvander@251
|
346 |
* Searches the call stack and returns true if the given package has any |
|
dvander@62
|
347 |
* active code running. This is an O(n) algorithm. |
|
dvander@62
|
348 |
*/ |
|
dvander@251
|
349 |
static bool IsInCallStack(Handle<Package> package); |
|
dvander@62
|
350 |
|
|
dvander@62
|
351 |
/* |
|
dvander@62
|
352 |
* Reclaim as much memory as possible. This pauses the calling thread |
|
dvander@62
|
353 |
* until garbage collection completes. |
|
dvander@62
|
354 |
*/ |
|
dvander@62
|
355 |
static void CollectGarbage(); |
|
dvander@64
|
356 |
|
|
dvander@64
|
357 |
/* |
|
dvander@64
|
358 |
* Clear any pending exception. |
|
dvander@64
|
359 |
*/ |
|
dvander@64
|
360 |
static void ClearPendingException(); |
|
dvander@65
|
361 |
|
|
dvander@65
|
362 |
/* |
|
dvander@65
|
363 |
* Executes a function with the given parameters. This interface is |
|
dvander@65
|
364 |
* intended for compatibility with SourceMod's ISourcePawnEngine2 and |
|
dvander@65
|
365 |
* should not be used otherwise, since it is intended to support only |
|
dvander@65
|
366 |
* a small subset of the core language. |
|
dvander@65
|
367 |
*/ |
|
dvander@129
|
368 |
static bool Invoke(Handle<Function> fun, const Parameter *params, unsigned nparams, |
|
dvander@129
|
369 |
bool checkTypes, int *result); |
|
dvander@69
|
370 |
|
|
dvander@69
|
371 |
/* |
|
dvander@69
|
372 |
* Sets the global message handler through which errors will be reported |
|
dvander@69
|
373 |
*/ |
|
dvander@69
|
374 |
static void InstallMessageReporter(IMessageReporter *reporter); |
|
dvander@69
|
375 |
|
|
dvander@195
|
376 |
/* Returns a new stack frame iterator object. */ |
|
dvander@69
|
377 |
static IStackFrameIterator *NewStackFrameIterator(); |
|
dvander@195
|
378 |
|
|
dvander@195
|
379 |
/* |
|
dvander@195
|
380 |
* Binds a native, by name, to an address. Natives are an ISPE1 concept |
|
dvander@195
|
381 |
* (originally from Pawn/Small's AMX API). In SourceMod 1, natives were |
|
dvander@195
|
382 |
* registered globally, but bound to plugins individually. We roughly |
|
dvander@195
|
383 |
* preserve that functionality here, by allowing host applications to |
|
dvander@195
|
384 |
* give us the name -> address mappings. |
|
dvander@195
|
385 |
* |
|
dvander@195
|
386 |
* Natives can be rebound or unbound any number of times. This function |
|
dvander@195
|
387 |
* fails if there is not enough memory. |
|
dvander@195
|
388 |
*/ |
|
dvander@195
|
389 |
static bool BindNative(const char *name, void *address); |
|
dvander@195
|
390 |
|
|
dvander@195
|
391 |
/* Sets the object that will listen for public functions. */ |
|
dvander@195
|
392 |
static void SetPublicFunctionListener(IPublicFunctionListener *listener); |
|
dvander@251
|
393 |
|
|
dvander@251
|
394 |
/* |
|
dvander@251
|
395 |
* Installs a system root folder. When an attempt to import locally fails, |
|
dvander@251
|
396 |
* the list of system roots are searched in the order they were installed. |
|
dvander@251
|
397 |
* |
|
dvander@251
|
398 |
* The given path must be absolute. It may contain a trailing slash. |
|
dvander@251
|
399 |
* |
|
dvander@251
|
400 |
* The name is an arbitrary, optional identifier that can be used to |
|
dvander@251
|
401 |
* build fully-qualified package identifiers. |
|
dvander@251
|
402 |
*/ |
|
dvander@251
|
403 |
static bool InstallSystemRoot(const char *path, const char *name); |
|
dvander@251
|
404 |
|
|
dvander@251
|
405 |
/* |
|
dvander@251
|
406 |
* Compiles a source file into a package and runs any initializers it has. |
|
dvander@251
|
407 |
* The file name must be a file name only, rather than a path. It may |
|
dvander@251
|
408 |
* optionally end in ".sp". If no ".sp" is provided, it is added |
|
dvander@251
|
409 |
* automatically. |
|
dvander@251
|
410 |
* |
|
dvander@251
|
411 |
* Note that if the file name (sans ".sp" extension) does not match the |
|
dvander@251
|
412 |
* regular expression /^[A-Za-z_][A-Za-z0-9_]+$/ then it will not be |
|
dvander@251
|
413 |
* importable from other files. |
|
dvander@251
|
414 |
*/ |
|
dvander@251
|
415 |
static bool Compile(Handle<Package> package, const char *name); |
|
dvander@62
|
416 |
}; |
|
dvander@60
|
417 |
|
|
dvander@60
|
418 |
/* |
|
dvander@64
|
419 |
* Suppresses exceptions. This is useful for calling API functions. When this |
|
dvander@64
|
420 |
* in scope, errors will be reported, but the exception will be cleared after. |
|
dvander@64
|
421 |
*/ |
|
dvander@64
|
422 |
class AutoClearExceptions |
|
dvander@64
|
423 |
{ |
|
dvander@64
|
424 |
public: |
|
dvander@64
|
425 |
~AutoClearExceptions() |
|
dvander@64
|
426 |
{ |
|
dvander@64
|
427 |
Keima::ClearPendingException(); |
|
dvander@64
|
428 |
} |
|
dvander@64
|
429 |
}; |
|
dvander@64
|
430 |
|
|
dvander@65
|
431 |
// Argument-passing interface for Invoke(). |
|
dvander@65
|
432 |
class Parameter |
|
dvander@65
|
433 |
{ |
|
dvander@65
|
434 |
public: |
|
dvander@65
|
435 |
enum Type { |
|
dvander@65
|
436 |
Int, |
|
dvander@65
|
437 |
Float, |
|
dvander@65
|
438 |
IntRef, |
|
dvander@65
|
439 |
FloatRef, |
|
dvander@65
|
440 |
Array, |
|
dvander@65
|
441 |
CharArray |
|
dvander@65
|
442 |
}; |
|
dvander@65
|
443 |
|
|
dvander@65
|
444 |
Parameter() |
|
dvander@65
|
445 |
{ |
|
dvander@65
|
446 |
} |
|
dvander@65
|
447 |
|
|
dvander@65
|
448 |
Parameter(int i) |
|
dvander@65
|
449 |
: type_(Int) |
|
dvander@65
|
450 |
{ |
|
dvander@65
|
451 |
u.i = i; |
|
dvander@65
|
452 |
} |
|
dvander@65
|
453 |
|
|
dvander@65
|
454 |
Parameter(int *i, bool writeback) |
|
dvander@65
|
455 |
: type_(IntRef), |
|
dvander@65
|
456 |
writeback_(writeback) |
|
dvander@65
|
457 |
{ |
|
dvander@65
|
458 |
u.ip = i; |
|
dvander@65
|
459 |
} |
|
dvander@65
|
460 |
|
|
dvander@65
|
461 |
Parameter(float f) |
|
dvander@65
|
462 |
: type_(Float) |
|
dvander@65
|
463 |
{ |
|
dvander@65
|
464 |
u.f = f; |
|
dvander@65
|
465 |
} |
|
dvander@65
|
466 |
|
|
dvander@65
|
467 |
Parameter(float *f, bool writeback) |
|
dvander@65
|
468 |
: type_(FloatRef), |
|
dvander@65
|
469 |
writeback_(writeback) |
|
dvander@65
|
470 |
{ |
|
dvander@65
|
471 |
u.fp = f; |
|
dvander@65
|
472 |
} |
|
dvander@65
|
473 |
|
|
dvander@65
|
474 |
Parameter(Type type, void *buffer, size_t length, bool writeback) |
|
dvander@65
|
475 |
: type_(type), |
|
dvander@65
|
476 |
writeback_(writeback), |
|
dvander@65
|
477 |
length_(length) |
|
dvander@65
|
478 |
{ |
|
dvander@65
|
479 |
assert(type == Array || type == CharArray); |
|
dvander@65
|
480 |
u.buffer = buffer; |
|
dvander@65
|
481 |
} |
|
dvander@65
|
482 |
|
|
dvander@65
|
483 |
Type type() const { |
|
dvander@65
|
484 |
return type_; |
|
dvander@65
|
485 |
} |
|
dvander@65
|
486 |
|
|
dvander@65
|
487 |
int i32() const { |
|
dvander@65
|
488 |
assert(type() == Int); |
|
dvander@65
|
489 |
return u.i; |
|
dvander@65
|
490 |
} |
|
dvander@65
|
491 |
float f() const { |
|
dvander@65
|
492 |
assert(type() == Float); |
|
dvander@65
|
493 |
return u.f; |
|
dvander@65
|
494 |
} |
|
dvander@65
|
495 |
int *i32p() const { |
|
dvander@65
|
496 |
assert(type() == IntRef); |
|
dvander@65
|
497 |
return u.ip; |
|
dvander@65
|
498 |
} |
|
dvander@65
|
499 |
float *fp() const { |
|
dvander@65
|
500 |
assert(type() == FloatRef); |
|
dvander@65
|
501 |
return u.fp; |
|
dvander@65
|
502 |
} |
|
dvander@65
|
503 |
bool writeback() const { |
|
dvander@65
|
504 |
assert(type() >= IntRef && type() <= CharArray); |
|
dvander@65
|
505 |
return writeback_; |
|
dvander@65
|
506 |
} |
|
dvander@65
|
507 |
size_t length() const { |
|
dvander@65
|
508 |
return length_; |
|
dvander@65
|
509 |
} |
|
dvander@65
|
510 |
void *buffer() const { |
|
dvander@65
|
511 |
assert(type() == Array || type() == CharArray); |
|
dvander@65
|
512 |
return u.buffer; |
|
dvander@65
|
513 |
} |
|
dvander@65
|
514 |
|
|
dvander@65
|
515 |
private: |
|
dvander@65
|
516 |
Type type_; |
|
dvander@65
|
517 |
bool writeback_; |
|
dvander@65
|
518 |
size_t length_; |
|
dvander@65
|
519 |
|
|
dvander@65
|
520 |
union { |
|
dvander@65
|
521 |
int i; |
|
dvander@65
|
522 |
float f; |
|
dvander@65
|
523 |
int *ip; |
|
dvander@65
|
524 |
float *fp; |
|
dvander@65
|
525 |
void *buffer; |
|
dvander@65
|
526 |
} u; |
|
dvander@65
|
527 |
}; |
|
dvander@64
|
528 |
|
|
dvander@61
|
529 |
class Internals |
|
dvander@61
|
530 |
{ |
|
dvander@61
|
531 |
template <typename T> friend class Root; |
|
dvander@61
|
532 |
|
|
dvander@61
|
533 |
private: |
|
dvander@195
|
534 |
static ke::HeapRoot *NewHeapRoot(); |
|
dvander@195
|
535 |
static void Destroy(ke::HeapRoot *root); |
|
dvander@61
|
536 |
}; |
|
dvander@61
|
537 |
|
|
dvander@61
|
538 |
template <typename T> void |
|
dvander@195
|
539 |
Root<T>::set(Handle<T> other) |
|
dvander@61
|
540 |
{ |
|
dvander@195
|
541 |
if (!other) { |
|
dvander@195
|
542 |
obj_ = other; |
|
dvander@61
|
543 |
return; |
|
dvander@195
|
544 |
} |
|
dvander@195
|
545 |
|
|
dvander@195
|
546 |
ke::Object **ptr = reinterpret_cast<ke::Object **>(*other); |
|
dvander@195
|
547 |
if (!root_) { |
|
dvander@195
|
548 |
root_ = Internals::NewHeapRoot(); |
|
dvander@195
|
549 |
if (!root_) |
|
dvander@195
|
550 |
return; |
|
dvander@195
|
551 |
} |
|
dvander@195
|
552 |
|
|
dvander@195
|
553 |
*reinterpret_cast<ke::Object **>(root_) = *ptr; |
|
dvander@195
|
554 |
obj_.obj_ = reinterpret_cast<T *>(root_); |
|
dvander@61
|
555 |
} |
|
dvander@61
|
556 |
|
|
dvander@195
|
557 |
template <typename T> |
|
dvander@195
|
558 |
Root<T>::~Root() |
|
dvander@61
|
559 |
{ |
|
dvander@195
|
560 |
if (!root_) |
|
dvander@61
|
561 |
return; |
|
dvander@195
|
562 |
Internals::Destroy(root_); |
|
dvander@61
|
563 |
} |
|
dvander@61
|
564 |
|
|
dvander@195
|
565 |
|
|
dvander@60
|
566 |
} |
|
dvander@60
|
567 |
|
|
danderson@96
|
568 |
#endif // _include_sourcepawn2_api_h_ |