1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2004-2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * SourcePawn. If not, see http://www.gnu.org/licenses/.
19 #ifndef _include_sourcepawn2_api_h_
20 #define _include_sourcepawn2_api_h_
24 #include "../include/keima_util.h"
40 * A Handle is a safe pointer that holds an object reference, such that it
41 * can be scanned and potentially moved by the garbage collector.
46 template <typename S> friend class Root;
48 template <typename S> void typeCheck() {
63 template <typename S> Handle(Handle<S> other)
64 : obj_(reinterpret_cast<S *>(*other))
69 explicit Handle(T *obj)
74 T *operator ->() const {
77 T *operator *() const {
80 operator bool () const {
89 * A local variable that roots an object. Locals are owned by the nearest
90 * HandleScope, and as soon as that HandleScope dies, all its Locals are
91 * no longer available.
94 class Local : public Handle<T>
102 template <typename S> Local(Local<S> other)
103 : Handle<T>(reinterpret_cast<T *>(*other))
105 this->template typeCheck<S>();
108 template <typename S> Local(S *other)
115 * A non-local variable that outlives HandleScopes. Unlike Local, a Root
116 * actually represents a rooted location. Roots must be allocated and
117 * disposed, and assignment to a root changes its contained object, not
118 * the location of the object.
120 template <typename T>
129 Root(Handle<T> other)
137 operator const Handle<T>() const {
141 bool operator ==(Handle<T> other) {
142 return Handle<T>(*this) == other;
144 Root<T> &operator =(Handle<T> other) {
150 void set(Handle<T> other);
157 * A HandleScope is where Local roots are allcoated. When the HandleScope
158 * is destroyed, all Handles created under it are also destroyed. HandleScopes
159 * may only be allocated on the stack, in LIFO order.
165 ke::Object **position_;
168 HandleScope(ke::Zone *zone, ke::Object **position, HandleScope *prev)
179 static ke::Object **CreateHandle(ke::Object *obj);
182 // Disallow silly stuff.
183 HandleScope(const HandleScope &);
184 void operator =(const HandleScope &);
185 void *operator new (size_t size);
186 void operator delete(void *, size_t);
191 // Error messages are pumped through this interface.
192 class IMessageReporter
195 virtual void onOutOfMemory() {
197 virtual void onUncaughtException(const char *message) {
199 virtual void beginCompilationErrors(const char *file) {
201 virtual void reportCompilationError(const char *message, unsigned line, unsigned col) {
203 virtual void endCompilationErrors() {
207 // For the purposes of error reporting, very basic information can be queried
208 // about the stack frame. This structure may be used to retrieve such
209 // information. During iteration, it is illegal to re-enter any scripted code
210 // or call any Keima functions that may cause garbage collection.
211 class IStackFrameIterator
214 virtual ~IStackFrameIterator() {
217 // Returns true if there are more frames, false otherwise.
218 virtual bool done() = 0;
220 // Returns the name of the current function. This may be NULL if the
221 // function is anonymous.
222 virtual const char *function() = 0;
224 // Returns the file of the current function. This will return an invalid
225 // path for C++ functions (for example, "<native>").
226 virtual const char *source() = 0;
228 // Returns the line number currently executing on this frame. For C++
229 // functions, this is always 0.
230 virtual unsigned lineNumber() = 0;
232 // Advance to the previous frame in the call stack.
233 virtual void prev() = 0;
236 // Listener interface for when public functions are registered or unregisted.
237 class IPublicFunctionListener
240 virtual ~IPublicFunctionListener() {
243 // Called when a public function becomes available to the runtime.
244 virtual void registerPublic(Handle<Function> fun) = 0;
246 // Called when a public is no longer available to the runtime.
247 virtual void unregisterPublic(Handle<Function> fun) = 0;
250 // A string is an immutable UTF8 buffer.
251 class KE_EXPORT String
254 // Returns the length of the string, in bytes.
257 // Returns the character buffer of the string, or NULL on failure. If the
258 // string is interned, chars() is guaranteed to succeed.
262 // A function is an executable unit of code.
263 class KE_EXPORT Function
266 // Returns the name of a function, which may be NULL. If not NULL, the
267 // string is guaranteed to be interned.
268 Local<String> name();
271 // A pubvar is an ISourcePawnEngine-compatible structure that holds information
272 // about public variables.
273 class KE_EXPORT Pubvar
276 // Returns the name of a pubvar, which is never NULL. The string is
277 // guaranteed to be interned.
278 Local<String> name();
281 // A module represents a single compiled file, and contains functions and
282 // global variables for that file (as well as exported types).
283 class KE_EXPORT Module
286 // Sets the native identity pointer, which is passed as the first argument
288 void setNativeIdentity(void *ptr);
295 * Initializes the Keima engine. This must be called exactly once before any
296 * other Keima functions are called. After this, it is safe to use Keima
297 * on the calling thread.
299 static bool Initialize();
302 * Shuts down the Keima engine and frees data structures on all threads.
304 static void Shutdown();
307 * Searches the call stack and returns true if the given module has any
308 * active code running. This is an O(n) algorithm.
310 static bool IsInCallStack(Handle<Module> module);
313 * Reclaim as much memory as possible. This pauses the calling thread
314 * until garbage collection completes.
316 static void CollectGarbage();
319 * Clear any pending exception.
321 static void ClearPendingException();
324 * Executes a function with the given parameters. This interface is
325 * intended for compatibility with SourceMod's ISourcePawnEngine2 and
326 * should not be used otherwise, since it is intended to support only
327 * a small subset of the core language.
329 static bool Invoke(Handle<Function> fun, const Parameter *params, unsigned nparams,
330 bool checkTypes, int *result);
333 * Sets the global message handler through which errors will be reported
335 static void InstallMessageReporter(IMessageReporter *reporter);
337 /* Returns a new stack frame iterator object. */
338 static IStackFrameIterator *NewStackFrameIterator();
341 * Binds a native, by name, to an address. Natives are an ISPE1 concept
342 * (originally from Pawn/Small's AMX API). In SourceMod 1, natives were
343 * registered globally, but bound to plugins individually. We roughly
344 * preserve that functionality here, by allowing host applications to
345 * give us the name -> address mappings.
347 * Natives can be rebound or unbound any number of times. This function
348 * fails if there is not enough memory.
350 static bool BindNative(const char *name, void *address);
352 /* Sets the object that will listen for public functions. */
353 static void SetPublicFunctionListener(IPublicFunctionListener *listener);
357 * Suppresses exceptions. This is useful for calling API functions. When this
358 * in scope, errors will be reported, but the exception will be cleared after.
360 class AutoClearExceptions
363 ~AutoClearExceptions()
365 Keima::ClearPendingException();
369 // Argument-passing interface for Invoke().
392 Parameter(int *i, bool writeback)
394 writeback_(writeback)
405 Parameter(float *f, bool writeback)
407 writeback_(writeback)
412 Parameter(Type type, void *buffer, size_t length, bool writeback)
414 writeback_(writeback),
417 assert(type == Array || type == CharArray);
426 assert(type() == Int);
430 assert(type() == Float);
434 assert(type() == IntRef);
438 assert(type() == FloatRef);
441 bool writeback() const {
442 assert(type() >= IntRef && type() <= CharArray);
445 size_t length() const {
448 void *buffer() const {
449 assert(type() == Array || type() == CharArray);
468 * Compiles a file and returns a Module.
470 extern Local<Module> Compile(const char *path);
474 template <typename T> friend class Root;
477 static ke::HeapRoot *NewHeapRoot();
478 static void Destroy(ke::HeapRoot *root);
481 template <typename T> void
482 Root<T>::set(Handle<T> other)
489 ke::Object **ptr = reinterpret_cast<ke::Object **>(*other);
491 root_ = Internals::NewHeapRoot();
496 *reinterpret_cast<ke::Object **>(root_) = *ptr;
497 obj_.obj_ = reinterpret_cast<T *>(root_);
500 template <typename T>
505 Internals::Destroy(root_);
511 #endif // _include_sourcepawn2_api_h_