Fixed type checking for multidimensional arrays.
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"
41 * A Handle is a safe pointer that holds an object reference, such that it
42 * can be scanned and potentially moved by the garbage collector.
47 template <typename S> friend class Root;
49 template <typename S> void typeCheck() {
64 template <typename S> Handle(Handle<S> other)
65 : obj_(reinterpret_cast<S *>(*other))
70 explicit Handle(T *obj)
75 T *operator ->() const {
78 T *operator *() const {
81 operator bool () const {
90 * A local variable that roots an object. Locals are owned by the nearest
91 * HandleScope, and as soon as that HandleScope dies, all its Locals are
92 * no longer available.
95 class Local : public Handle<T>
103 template <typename S> Local(Local<S> other)
104 : Handle<T>(reinterpret_cast<T *>(*other))
106 this->template typeCheck<S>();
109 template <typename S> Local(S *other)
116 * A non-local variable that outlives HandleScopes. Unlike Local, a Root
117 * actually represents a rooted location. Roots must be allocated and
118 * disposed, and assignment to a root changes its contained object, not
119 * the location of the object.
121 template <typename T>
130 Root(Handle<T> other)
138 operator const Handle<T>() const {
142 bool operator ==(Handle<T> other) {
143 return Handle<T>(*this) == other;
145 Root<T> &operator =(Handle<T> other) {
151 void set(Handle<T> other);
158 * A HandleScope is where Local roots are allcoated. When the HandleScope
159 * is destroyed, all Handles created under it are also destroyed. HandleScopes
160 * may only be allocated on the stack, in LIFO order.
166 ke::Object **position_;
169 HandleScope(ke::Zone *zone, ke::Object **position, HandleScope *prev)
180 static ke::Object **CreateHandle(ke::Object *obj);
183 // Disallow silly stuff.
184 HandleScope(const HandleScope &);
185 void operator =(const HandleScope &);
186 void *operator new (size_t size);
187 void operator delete(void *, size_t);
192 // Error messages are pumped through this interface.
193 class IMessageReporter
196 virtual void onOutOfMemory() {
198 virtual void onUncaughtException(const char *message) {
200 virtual void beginCompilationErrors(const char *file) {
202 virtual void reportCompilationError(const char *message, unsigned line, unsigned col) {
204 virtual void endCompilationErrors() {
208 // For the purposes of error reporting, very basic information can be queried
209 // about the stack frame. This structure may be used to retrieve such
210 // information. During iteration, it is illegal to re-enter any scripted code
211 // or call any Keima functions that may cause garbage collection.
212 class IStackFrameIterator
215 virtual ~IStackFrameIterator() {
218 // Returns true if there are more frames, false otherwise.
219 virtual bool done() = 0;
221 // Returns the name of the current function. This may be NULL if the
222 // function is anonymous.
223 virtual const char *function() = 0;
225 // Returns the file of the current function. This will return an invalid
226 // path for C++ functions (for example, "<native>").
227 virtual const char *source() = 0;
229 // Returns the line number currently executing on this frame. For C++
230 // functions, this is always 0.
231 virtual unsigned lineNumber() = 0;
233 // Advance to the previous frame in the call stack.
234 virtual void prev() = 0;
237 // Listener interface for when public functions are registered or unregisted.
238 class IPublicFunctionListener
241 virtual ~IPublicFunctionListener() {
244 // Called when a public function becomes available to the runtime.
245 virtual void registerPublic(Handle<Function> fun) = 0;
247 // Called when a public is no longer available to the runtime.
248 virtual void unregisterPublic(Handle<Function> fun) = 0;
251 // A string is an immutable UTF8 buffer.
252 class KE_EXPORT String
255 static Local<String> NewAscii(const char *str);
257 // Returns the length of the string, in bytes.
260 // Returns the character buffer of the string, or NULL on failure. If the
261 // string is interned, chars() is guaranteed to succeed.
265 // A function is an executable unit of code.
266 class KE_EXPORT Function
269 // Returns the name of a function, which may be NULL. If not NULL, the
270 // string is guaranteed to be interned.
271 Local<String> name();
273 // Returns the package the function was created in.
274 Local<Package> package();
277 // A pubvar is an ISourcePawnEngine-compatible structure that holds information
278 // about public variables.
279 class KE_EXPORT Pubvar
282 // Returns the name of a pubvar, which is never NULL. The string is
283 // guaranteed to be interned.
284 Local<String> name();
287 // A package is a collection of compiled files and possibly sub-packages.
288 // Internally, packages are used to implement the "import" statement. However,
289 // the host application can also create packages to organize related files,
290 // restrict import visibility, or implement hot swapping of loaded modules.
291 class KE_EXPORT Package
297 // The package cannot be accessed from any import statement.
300 // Source files compiled in this package cannot import names in the
305 // Creates a package. The parent package may be NULL. The name can be NULL
306 // as well. |path| must be a filesystem path, which will be normalized
307 // according to OS-specific rules.
308 static Local<Package> New(Handle<Package> parent,
313 // Returns the name of the package, which may be NULL. The string is
314 // guaranteed to be interned.
315 Local<String> name();
317 // Returns the full path of the package. The string is guaranteed to be
319 Local<String> path();
321 // Sets the package's native identity. This is a host-application defined
322 // value that is passed to native callbacks. Packages created under this
323 // one will automatically inherit this native identity.
324 void setNativeIdentity(void *identity);
326 // Returns the package's native identity, or NULL if none was set.
327 void *getNativeIdentity();
334 * Initializes the Keima engine. This must be called exactly once before any
335 * other Keima functions are called. After this, it is safe to use Keima
336 * on the calling thread only. It is not safe to race on calling this.
338 static bool Initialize();
341 * Shuts down the Keima engine and frees data structures on all threads.
343 static void Shutdown();
346 * Searches the call stack and returns true if the given package has any
347 * active code running. This is an O(n) algorithm.
349 static bool IsInCallStack(Handle<Package> package);
352 * Reclaim as much memory as possible. This pauses the calling thread
353 * until garbage collection completes.
355 static void CollectGarbage();
358 * Clear any pending exception.
360 static void ClearPendingException();
363 * Executes a function with the given parameters. This interface is
364 * intended for compatibility with SourceMod's ISourcePawnEngine2 and
365 * should not be used otherwise, since it is intended to support only
366 * a small subset of the core language.
368 static bool Invoke(Handle<Function> fun, const Parameter *params, unsigned nparams,
369 bool checkTypes, int *result);
372 * Sets the global message handler through which errors will be reported
374 static void InstallMessageReporter(IMessageReporter *reporter);
376 /* Returns a new stack frame iterator object. */
377 static IStackFrameIterator *NewStackFrameIterator();
380 * Binds a native, by name, to an address. Natives are an ISPE1 concept
381 * (originally from Pawn/Small's AMX API). In SourceMod 1, natives were
382 * registered globally, but bound to plugins individually. We roughly
383 * preserve that functionality here, by allowing host applications to
384 * give us the name -> address mappings.
386 * Natives can be rebound or unbound any number of times. This function
387 * fails if there is not enough memory.
389 static bool BindNative(const char *name, void *address);
391 /* Sets the object that will listen for public functions. */
392 static void SetPublicFunctionListener(IPublicFunctionListener *listener);
395 * Installs a system root folder. When an attempt to import locally fails,
396 * the list of system roots are searched in the order they were installed.
398 * The given path must be absolute. It may contain a trailing slash.
400 * The name is an arbitrary, optional identifier that can be used to
401 * build fully-qualified package identifiers.
403 static bool InstallSystemRoot(const char *path, const char *name);
406 * Compiles a source file into a package and runs any initializers it has.
407 * The file name must be a file name only, rather than a path. It may
408 * optionally end in ".sp". If no ".sp" is provided, it is added
411 * Note that if the file name (sans ".sp" extension) does not match the
412 * regular expression /^[A-Za-z_][A-Za-z0-9_]+$/ then it will not be
413 * importable from other files.
415 static bool Compile(Handle<Package> package, const char *name);
419 * Suppresses exceptions. This is useful for calling API functions. When this
420 * in scope, errors will be reported, but the exception will be cleared after.
422 class AutoClearExceptions
425 ~AutoClearExceptions()
427 Keima::ClearPendingException();
431 // Argument-passing interface for Invoke().
454 Parameter(int *i, bool writeback)
456 writeback_(writeback)
467 Parameter(float *f, bool writeback)
469 writeback_(writeback)
474 Parameter(Type type, void *buffer, size_t length, bool writeback)
476 writeback_(writeback),
479 assert(type == Array || type == CharArray);
488 assert(type() == Int);
492 assert(type() == Float);
496 assert(type() == IntRef);
500 assert(type() == FloatRef);
503 bool writeback() const {
504 assert(type() >= IntRef && type() <= CharArray);
507 size_t length() const {
510 void *buffer() const {
511 assert(type() == Array || type() == CharArray);
531 template <typename T> friend class Root;
534 static ke::HeapRoot *NewHeapRoot();
535 static void Destroy(ke::HeapRoot *root);
538 template <typename T> void
539 Root<T>::set(Handle<T> other)
546 ke::Object **ptr = reinterpret_cast<ke::Object **>(*other);
548 root_ = Internals::NewHeapRoot();
553 *reinterpret_cast<ke::Object **>(root_) = *ptr;
554 obj_.obj_ = reinterpret_cast<T *>(root_);
557 template <typename T>
562 Internals::Destroy(root_);
568 #endif // _include_sourcepawn2_api_h_