A small and fast typed language for embedding in host applications.
SourcePawn is an independent project from SourceMod, however SourceMod is its largest and possibly only consumer. Changes tend to be geared toward compatibility and efficiency with SourceMod and typical SourceMod programs. Their version numbers are currently synchronized.
Make sure you have Python 3 and AMBuild installed.
To build on Linux/macOS/POSIX environments:
std::filesystem
support probably
work.To build on Windows:
std::filesystem
support
will work as well.Once you have your build environment set up, you can clone and build SourcePawn:
git clone --recursive https://github.com/alliedmodders/sourcepawn
cd sourcepawn
python3 configure.py --out obj
ambuild obj
SourcePawn "should" run on any architecture. It has been tested on ARMv7, ARMv8, x86, and x86_64. However, only x86 currently has a just-in-time (JIT) compiler. Other architectures fallback to an interpreter (albeit, a very simple and efficient one).
When emitting binaries, SourcePawn does not take platform endianness into account. Thus, a .smx
file produced by the compiler will only work on architectures of the same endianness. Otherwise,
they are cross-platform.
SourcePawn has a regression test suite. You can run it against a build directory like so:
python tests/runtests.py objdir
There is also a large corpus containing GPL scripts. This corpus gets run on every commit. If a change is designed to intentionally break something, the corpus gets adjusted as needed. You can get and run the corpus like so:
git clone https://github.com/dvander/sourcepawn-corpus
cd sourcepawn
python tools/corpus/run.py objdir/path/to/spcomp ../sourcepawn-corpus -j 24 --fail-fast
It is recommended to use a machine with many cores and to use as many of those cores as possible
(-j N
). The corpus has thousands of plugins and can take a long time on a single core.
The SourcePawn source tree is divided into the following folders:
compiler
- The legacy compiler, currently used in SourceMod.vm
- The virtual machine and just-in-time compiler.exp
- Experimental projects.
compiler
- The v2 compiler for SourcePawn 1.7.docgen
- The documentation generator and web frontend.tools
docparse
- Parse files into JSON that can be consumed by documentation generators.SourcePawn has a long history - or rather, pre-history. It ultimately comes from SmallC, a language which appeared in Dr. Dobb's Journal in 1984.
Thiadmer Riemersma of ITB CompuPhase adopted this code to make a platform-independent language that could run on tiny embedded CPUs, such as 16-bit microcontrollers [1]. Thiadmer made sweeping changes to the language that made it less of a C dialect, so he renamed it to "Small". In particular, pointers were removed in favor of references, and the language became untyped. Each value in Small was a "cell". Cells could have tags, and operators could be defined for tags - but tags were not types. They could not change the storage width, they did not participate in a type system, and they were not type-checked.
Around 2000, Alfred Reynolds chose to use Small 1.8 as the scripting language for Admin-Mod, the first hugely popular Half-Life 1 server extension system. Admin-Mod had a lasting impact on the development scene for Valve-related games, and the choice to use Small extended to other systems as well. AMX Mod used Small 2.7, and when AlliedModders forked it for AMX Mod X, it took version 2.7 as well.
ITB CompuPhase renamed Small to "Pawn" in 2005 for better searchability. This renaming coincided with a 3.0 release. AMX Mod X upgraded to Pawn 3.0, which it still uses today.
In early 2006, Borja Ferrer ("faluco") and the author chose to re-use Pawn in SourceMod, but reimplemented the VM. Pawn had a crufty C API, and its JIT was written in self-modifying assembly. We introduced an object-oriented VM and replaced the JIT with a macro assembler written in C++. In the compiler frontend, AlliedModders made some notable changes:
Because these changes were fairly invasive, we renamed the language to "SourcePawn", and pinned the compiler to upstream version 3.2. We consider it an independent project and do not take upstream Pawn changes.
The new VM included a few important changes in design:
The initial implementation of the VM API was embedded directly in SourceMod, and the JIT was a separate closed-source binary.
Additionally, a problem was anticipated from AMX Mod X: many values backed by C++ data structures were opaque and therefore not well typed. As an attempt to mitigate this, a "Handle" system was introduced similar to file or kernel objects from operating systems. It was a tuple of 16-bit values, a serial number and an index into a Handle table. Each slot in the Handle table was typed (types were registered by participating API) and objects participating in the Handle API were internally reference counted.
The Handle system was not part of the VM, and although it provided many benefits over precursor systems, this proved to have severe impact on the future ability to make Pawn garbage-collection-safe. The bare API provided no way to safely communicate the lifetime of values in the VM.
SourcePawn 1.1 was released with SourceMod 1.1, on December 28th, 2008.
This was a major refactoring of SourcePawn internals:
There were no language changes.
For the SourceMod 1.4 release (October 28, 2011), many O(n^2) algorithms were removed from the SourcePawn compiler to improve performance.
SourcePawn 1.2 was released with SourceMod 1.6, on July 3rd, 2013.
A string literal concatenation operator was pulled from upstream Pawn.
The virtual machine received many changes:
SourcePawn 1.7 was released with SourceMod 1.7 on February 4th, 2015.
The language has received a major (largely backwards compatible) overhaul called the "Transitional Syntax". This introduces more C-like type declarations, more formal type checking, and the ability to simulate object-oriented behavior via "methodmaps". In addition, the compiler was ported to C++ for maintainability.
SourcePawn 1.8 was released with SourceMod 1.8 on June 5th, 2016.
A few minor language bugs were fixed. Internally, the VM received a large overhaul to error-handling to improve stack frame dumps and future exception handling capabilities. The interpreter was removed.
SourcePawn 1.9 was declared stable on October 2nd, 2017.
It now includes a new reference interpreter, and will officially build and run on platforms other than x86.
SourcePawn 1.10 was declared stable on September 15th, 2019.
The biggest change in this release is an improved syntax for "enum structs" that works with Transitional Syntax. More information can be found here.
Other changes:
funcenum
and functag
keywords.SourcePawn 1.11 was released on July 1, 2022.
This release contains a rewrite of the parser, fully eliminating the multi-pass reparse model. We now properly generate an Abstract Syntax Tree (AST). Semantic checks and code generation are completely separate phases. Compiler speed is improved by 2-3X.
This release also contains stricter type checking and much better handling of array initializers. In particular, the fully relocatable indirection vector algorithm has been removed. This greatly simplifies array generation and access code. Array generation as been moved to dedicated opcodes, necessitating a version compatibility bump. Array declaration and access will be much faster for multi-dimensional arrays.
Also as of this release, both the compiler and VM can run on non-x86 platforms (such as ARM).
SourcePawn 1.12 is currently in development.
This release contains a number of bug fixes and internal improvements. It also greatly improves error message readability in the style of modern compilers.
This release contains a number of language changes.
INVALID_FUNCTION
is now type null_t
. The old internal type nullfunc_t
has been removed.
INVALID_FUNCTION
and null
are now equivalent, which means code manually checking for -1
will not work. There are three functions added to IPluginContext
to help native code with
this change: GetNullFunctionValue()
, IsNullFunctionId()
, and GetFunctionByIdOrNull()
.