search on Google
internet angelcode.com

Work in progress

You can always find the latest version of AngelScript in the SVN on SourceForge.net. There you can download a tar ball with the latest revision or browse the repository online.

If you prefer to use an SVN client to download the code, point your client to the following address:

https://angelscript.svn.sourceforge.net/svnroot/angelscript/trunk

I recommend TortoiseSVN as the SVN client if you're using Windows, otherwise the original SVN is the best alternative.

Version 2.19.0 WIP - 2010/03/14

  • Nothing yet

Known bugs

Changes planned for later versions

These are some of the changes that I'm thinking about. Not all of these may actually be implemented, some may be implemented a bit differently than described, but all describe my current thoughts.

The list is ordered roughly by priority. The item I'll implement next depends mostly on the complexity on the feature, my current interest, and feedback from the user base.

You're always welcome to send me your comments on current and/or upcoming features.

version 3.0.0 requirements

  • Remove the built-in array type. Arrays are supported as add-ons.
  • Support for function pointers, so that the function binding through imports can be removed.
  • Change script language parameter references to simplify syntax
  • Addition of access profiles for individual registered types/functions
  • Change to caller owns object handles.
  • Separate compiler from the rest of the engine, so that it is possible to build applications without the compiler.
  • Platform independent pre-compiled bytecode for compiling on one platform and executing on another.
  • TypeId and asIObjectType should be removed. asITypeInfo should be introduced instead.
  • function id should be removed. asIScriptFunction pointers should be used instead.
  • Remove the syntax for declaring dynamic array types, i.e. int[] arr;. Dynamic arrays should be declared as the template type, e.g. array<int> arr;. Static arrays (when implemented) should still be declared with int arr[];

planned for next releases

  • asEP_CALLER_OWNS_HANDLE
  • Implement implicit factory/constructor behaviours for implicit cast from primitive type to object type.
  • Allocate value types on the stack instead of on the heap.
    • Need to change how objects are returned by value in the scripts
  • Allow scripts to return references. Then change the index behaviour to the opIndex method.
  • Make the saved bytecode smaller and platform independent.
  • Allow recompiling bytecode without destroying objects. In this mode, functions with the same function signature will simply have the bytecode updated, but will otherwise remain the same. There are obviously restrictions for this to work. Classes cannot change its properties, interfaces cannot change its members, global variables cannot change types, etc.

planned for 2.19.0


Library

Improved documentation

Some suggestions for improved documentation:

  • Expand the pages on script classes. Show script example on how to use script classes (no need for 'new' keyword, temporary object, inheritance, polymorphing, const correctness)
  • Show script example on how to use script arrays (how to resize, initialization lists, declaration, etc)
  • Explain how function overloading works and how the compiler determines which function to call based on argument types.
  • Explain how a script class can be passed to the application
  • Add a page on the customization options. Preprocessor defines for compile time changes. Engine properties. Add-ons.
  • Case study 1: using script classes to implement controllers for game entitites (can even use an abstraction layer to allow substituting the script controller for C++ dlls)
  • Case study 2: using global script functions to implement the controllers
  • Case study 3: implementing animation with co-routine
  • Why use scripts: explain my view on why use scripting : safety, easily modified, remote debugging, etc
  • Usage examples for asCALL_GENERIC
  • Explain why the asBEHAVE_VALUE_CAST doesn't allow casts to bool.

Improved garbage collection

The garbage collector should have the notion of long lived and short lived objects. Long lived objects will not be checked for circular references that often. Short lived objects will be checked for circular references a few times, and then upgraded to long lived.

Some objects, such as script functions and global variables, will always be marked as long lived.

Improve Getters and Setters for properties

Allow registered get methods to use output parameter instead of return value to return the property value.

Allow the property accessors to access a real property of the same name without going into a loop.

Allow use of property accessors with indexes to wrap native C++ arrays. Suggestion by Bismuth

Allow use of compound assignment with property accessors, where possible. Forum thread. If the property is an object and the object has the compound assignment operator, what should be done then? For primitives we know what the result should be, but for object we do not so we cannot rewrite it to 'o = o + e', since the += operator may not do a simple addition.

More options for dynamic modules

Allow the compilation of new script sections to existing modules. The code should be merged with the already built code. When the functions overlap, they should either be replaced, or an error should be given.

I'm not quite sure how this will work, but it is something I would like to add.

Improved memory usage

Right now the compiler will compile all the code in a script, whether it is used or not. It would be great if the application could tell the compiler which would be the entry points, so that the compiler could simply discard the rest of the stuff thus freeing up memory.

Some other stuff that isn't necessary to keep around is the enums and typedefs that won't be used again unless other compilations are done.

Support smart pointers

What can be done to support smart pointers?

Smart pointers is a class that holds a pointer to the real object. The class usually has the -> operator overloaded so that accessing members of the real object works just like accessing members through a normal pointer. The smart pointer may also take care of reference counting.

When registering the type controlled by a smart pointer it would be necessary to tell AngelScript that it is a smart pointer. A new special behaviour is necessary to register the -> operator so that the VM can automatically access the true object. When registering the members of the object it would also be necessary to indicate which members are accessed through the -> operator, and which are accessed directly.

How would it work to pass objects of this type to application functions, or return them from application functions? Usually objects held in smart pointers, are passed as normal references to application functions, but sometimes it really is a reference to the smart pointer itself.

It should be completely transparent to the scripts if an object is a smart pointer or not.

Custom operator tokens

It would be interesting to allow the application to define it's own operator tokens and the class methods that implement them. The application could then add operators for things like dot product or cross product. It may even be possible to simplify the core library with this.

Module access profiles

The application should set the modules access profile per entity, rather than per config group. The access profile is a bit mask where the bitmask for the registered entity will be compared with the access profile for the module to see if the module has access or not to the entity.

The access profile can be different for an object type and its methods, thus allowing modules to have access to different set of methods depending on their profile. The object's behaviours are always in the same access profile as the type itself though (or maybe not? It may be interesting to allow different profiles for factories, for example).

The config groups will still be removed as a whole.

The access profile should be set as a parameter when registering the type or function. The parameter should be optional (with value 0), and will by default add the type/function to all profiles. There will not be any Begin/End functions for setting access profiles. We may use an engine property to set the default access profile, if necessary.

The module's access shouldn't be set in the module, but rather be given as a flag to the compiler when the compilation is done.

User data

The asIScriptContext and asIScriptEngine should have a way of registering a function to clean up the user data once the context/engine is destroyed.

Suggestion by SiCrane

Improved multithread support

Add multithreaded support for more platforms. Add documentation for how to turn off multithreading for performance improvements in non-multithreaded environments. We may also be able to optimize the multithreaded code slightly by using code from LDK library, suggestion by Lorien Dunn.

Allow applications to disable global variables in scripts through an engine property. This is useful if the application plan on having multiple threads execute scripts from the same module simultaneously and don't want to burden the script writer with having to think about how to control the access to the global variables to avoid memory corruption.

Multiple OS fibers

Look into properly supporting switch of OS fibers from within script contexts. Perhaps we need to use a fiber local storage for the stack of active contexts in order to permit this kind of switching.

Currently if you have two contexts running in different fibers that switch between each others from within asCScriptContext::Execute, the asGetActiveContext() function may not return the correct context. In debug mode it may cause assert failures, as there is a check when popping the active context to make sure it is the correct one that is popped.

A switch of fibers from within asCScriptContext::Execute may also leave loose reference on the context stack if the application registered function that performs the switch is not properly implemented. To guarantee no loose references, the function should be a void function that takes no arguments. This way the script can only call it as a simple function call, rather than in a complex expression.

Optimize strings

The string constants used throughout the scripts should be instanciated once by the compiler and stored in a pool. The generated code will then receive constant references to these pooled strings. This will greatly improve performance for scripts that does a lot of string comparisons with constant strings, and will also permit application conversion of string constants from 8bit to 16bit for example.

Consider adding the primitive type 'text' which is basically a 'const char * char'. The string literals would be of this type, instead of the registered string type. When assigning one 'text' variable to another, only the pointer is copied, without any reference counting.

The 'text' type has some tempting advantages in that they are fast and efficient. They would also allow registration of C++ functions that take 'char *' as parameters. However, there are problems that needs to be addressed before taking this step, how should memory management be handled? What if the script stores a 'text' variable somewhere and then discard the module that compiled the text literal? The application writer could also be tempted to write functions that return 'text' literals to the script, how should this be handled?

Improved memory management for value types

Now that the application registers types as either reference types or value types, the script engine should take advantage of this and allocate value types on the stack rather than on the heap. The same for the array object.

Better validation of registered functions

I would like to provide means for automatically validating the signature of the registered functions. If AngelScript provides an interface for determining the parameter types, based on function id, the application can use templates to automatically validate all of the parameters. It isn't possible to automatically generate the function declaration by means of templates, e.g. should a parameter reference be a &in, &out, or &inout? But it is possible to verify that a AngelScript parameter reference is mapped to parameter reference in C++. Doing this automatically, it will be easier to avoid stack corruption when AngelScript calls the C++ function.

Stack corruption happens for example when AngelScript passes a structure by value, but the C++ function expects a reference, or if the C++ function returns a value in memory, but the function was registered as void.

Can the calling convention be determined with means of templates? I.e. is it possible to use templates to determine whether a function should be asCALL_CDECL or asCALL_STDCALL? Example code from SiCrane

Add a way to obtain the function id of the system function being called

It may be useful to be able to obtain the function id, of the system function that is currently being called by the context. From the function id the name of the function and its signature can also be obtained. Suggested by Jeff Slutter.

Registered comparison operator

For application registered types that register the comparison operators directly the engine could automatically construct an opCmp method so that the compiler doesn't have to bother with all different behaviour types.

If only the equality operator is registered then only the opEqual function will be supported. To be able to do all comparisons, one equality behaviour and one relational comparison behaviour is needed. Example: "less than" and "equal". The function will first compare with "less than", and if not less, it will compare with "equal".

All script code should be resumable

Currently there are moments where script code is executed but the application cannot control the execution, e.g. with the Build() call where the global variables are initialized with a call to the internal @init script functions, with the CreateScriptObject() where the constructor of a script class may be called, with script array resizing where the constructor for each of the elements are called.

Some changes will be necessary to give the application complete control over script code that is executed. CreateScriptObject and Build will be able to use an application supplied context instead of creating its own. This will be done similar to how ExecuteString currently does it.

The script array object will also be modified to use a script function to perform the initialization of the elements. Script code can then call that script function directly instead of calling a C++ function that has to create a new context to initialize the elements. The asIScriptArray interface will of course maintain the C++ resize method, but it can internally call the same script function to initialize the elements, and permit the use of an application supplied context.

Improving context interface for calling script functions

I need a single function that can be used to set any argument. Something like SetArgValue(int index, void *ptrToValue, bool takeOwnership = false).

When the argument is an object handle and takeOwnership is false, the context will automatically increase the reference count. If takeOwnership is true, the context won't increase the reference count, which means the application must not release it.

When the argument is an object by value, the context will automatically create a copy of the object, unless takeOwnership is true, in which case the context will store the object pointer and then release it upon completion.

Shared type ids

Currently, if interfaces are declared equally in two different modules they will share the type id, so that objects that implement this interface can be exchanged between the modules without any difficulties.

I need to expand this to other types, such as typedefs and enums, as well.

Classes are a bit more complicated, because they come attached with function implementation, which may access global variables, or other types that are not shared, etc.

Improved portability

  • Improved support for complex types in native calling conventions on PPC

    PPC has very complex calling convetions and although AngelScript handles most cases well, it has problems when passing complex types around by value, either in parameters or as return value. For example a structure with only float values should be passed in the registers instead of in memory. Likewise, there is a vector type that has its own registers that AngelScript doesn't even know about yet.

    In order to be able to support functions natively (the generic interface already works) that pass these types around by value, AngelScript must know the exact layout of the structure. A change to the way types are registered is needed to support this, and the PPC native code must also be improved.

    A simple template helper function could be written that will allow values to be passed by value rather than by pointer. Otherwise you won't be able to call the function with a literal constant value.

  • Native calling conventions on more compilers/platforms

    64bit Mac OS X is possibly the last major platform that AngelScript doesn't have support for native calling conventions on. I don't have access to a 64bit Mac OS X, so unless someone can contribute the code it will probably be a while before I get to this.

    Remember that although native calling conventions are not supported on all platforms the library still works by using the generic calling convention, so the support for native calling conventions is only for convenience/performance sake.

  • Multithreading support on more platforms

    The multithreading support must be expanded to more platforms. Currently only Win32 and posix enabled systems can use multithreading.
  • Indicator for non-trivial copy constructor

    The existance of a non-trivial copy constructor is often used to decide how an object is passed/returned by value. Will probably need to add something like asOBJ_APP_COPY_CONSTRUCT. Reference.

AngelScript calling convention

Objects parameters

All objects should be passed by reference, as if it was a const reference. The script functions that access object parameters for modification will copy the object first and then access the copy instead. Application registered functions that register parameters with non-const input reference should be wrapped automatically, by the compiler to pass a copy of the object to the parameter.

This will allow me to remove parameter references from the script language, without loosing the performance benefits of using const &in references.

Parameters can still be declared as const, but it won't make a difference to the caller, as it will always pass parameters expecting them not to be modified. This may affect function overloading.

Object handles

The caller should be the owner of the object handles passed to functions. This will reduce the number of addref/release calls made during script execution. It will also simplify the registered application functions, as they will no longer have to release the handles received in parameters.

The script compiler will need to make sure that all object handles passed to functions are stored in local variables (or parameters in the function). This is similar to how the compiler currently guarantees the validity of references.

In order to avoid abrupt changes to applications I'll implement this feature as an engine property: asEP_CALLER_OWNS_HANDLE. The value will be false by default. After a few releases I can change the default to true. Then after even more releases, the engine property can be removed all together.

Improved object type registration

Look into what to do with asOBJ_NOHANDLE and ALLOW_UNSAFE_REFERENCES. Currently the engine permits the types to be passed by reference. It probably shouldn't allow that, but is it necessary to block it?

Can we determine the asOBJ_APP flags through templates without loosing portability?

Cloning modules

Cloning modules will create an identical copy of the first module. The result should be the same as if a second module had been compiled with the same script.

The function ids for each module will be different, as a function id is a global id the uniquely identifies a function in the engine. The same goes for object types. This is especially important when the functions/classes accesses global variables in the module.

Interface ids will however remain the same for both modules.

A module can also be cloned by saving the bytecode from one module and then reloading it into another. But if the script engine can clone the modules directly it will be faster than having the application take care of it.

A common super class for all script classes

Maybe a super class for all script classes can be implemented. The super class, won't have any properties or methods. It is only used as a common base, so that all classes can be stored in a common way. It could also be seen as an interface that all classes implement.

Potential drawback: Application registered classes won't always be derived from the super class, thus separating them from the script classes.

Advantage: All script classes will have a common denominator, facilitating the storage of them. An application registered class that derive from an AngelScript class interface, can be registered to have this same common denominator which should make it possible to have script classes inherit from application registered classes.

Evaluate the possibility of using dynamic calls

It might be possible to implement something like dispatch calls in AngelScript. This is something that would work for any object, and may make it easier to write scripts for some situations. What the compiler would do is something like this: 1) build a list of arguments, including a reference to the object, as well as the name of the function. 2) call a built in dispatch function. The dispatch function would then check the object type to find the matching method and calling it. If no matching method is found an exception is thrown. Combine this with the generic superclass Object that all classes inherit from and you have a completely dynamic type. A special dispatch operator would be needed so that the script writer can choose compile time or run time resolution of the method. Possible syntax: object->function(23, 43)

Investigate possibility of allowing reference cast behaviours for value types

Currently it is not possible to establish class hierarchies for value types. What would the implications of allow this be? Is there any danger of allowing a temporary reference cast?

Improve template classes

Must be possible to register template types with more than one subtype, i.e. map<string,int>.

Remove built-in dynamic array objects

Related to: static arrays

The built-in dynamic array type will be removed. This will happen when I release version 3.0.0.

Allow initialization lists for registered types

Related to: dynamic arrays

It must be possible to register types that accept initialization through initialization lists. This probably needs a new way of registration. Possibly a way to tell AngelScript which constructor should be used, and then which index behaviours.

It would be great if the application could tell AS if a special pattern is needed for the initialization lists, for example a map may need to be initialized with alternating types, e.g. {string, int, string, int}. Or perhaps {{string, int}, {string, int}}

Use copy constructor for initializations

AngelScript currently creates the object with the default constructor and then does an assignment. It would be more efficient to use the copy constructor directly.

More engine properties

Possible engine properties:
  • NO_64BIT_TYPES, which removes double, int64, uint64, etc.
  • MAX_PORTABILITY, which removes support for native calling conventions.
  • ALLOW_POINTERS, add support for pointers.
  • NO_GLOBAL_STATEMENTS, which disables the use of global variables/statements in scripts. Default: FALSE.
  • NO_IMPORTS, which disables the use of bound functions in modules. Default: TRUE.
  • ALLOW_BOOL_CAST, which adds implicit conversion to/from bool
  • REMOVE_LINE_CUES_BETWEEN_TRIVIAL_STATEMENTS, this does a slightly less radical optimization than BUILD_WITHOUT_LINE_CUES. SUSPEND instructions for statments that make calls to other functions or conditional branches will be kept to allow proper debugging. This one will be important for JIT compilation as it will allow longer sequences of bytecode to be transformed into machine code.

Allow importing of classes from other modules

Requires: class prototypes

Add support for importing class definitions from other modules, so that a class can be implemented in one module yet used in another.

Support for UTF16 encoded scripts

AngelScript already supports scripts encoded in UTF-8. It also supports UTF-16 encoded string literals through the engine property asEP_STRING_ENCODING.

Adding a UTF-16 code scanner for the compiler might be interesting. This would allow applications to avoid having to convert script code to UTF-8 before compiling it.

This is very low priority though.

Automatic translation of the string type to other C++ built-in types

In C++ it is very common to use at least two different representations of character strings, e.g. std::string and char*. I want to allow AngelScript to automatically translate the registered string type to either of them so that the application doesn't have to use wrapper functions.

It will probably need a new behaviour on the string type, as well as a new indicator when registering the function that needs the translation.

Suggestion by Manu Evans.

Registration of true constants

It should be possible to register literal constants.

Catch application exceptions when calling registered functions

Add a try/catch(...) around calls into the application registered functions. Obviously this will not be able to treatment based on type of exception, but it may stop the application from working due to application exceptions. These try/catch statements will be optional via preprocessor flags.

Support for @+& (autohandles with reference to handle)

This requires that the script engine keeps a copy of the value before going into the function, then upon return increases the reference on the returned handle, and then decreases the reference on the previous handle.

Suggestion by Dentoid.

Improved memory footprint

I've made great improvements on the memory footprint already, but at some time I will probably go back to this problem to see if I can improve it even further.

Statement blocks can be parsed one statement at a time, which will improve memory utilization when compiling large script functions.

Need engine properties to discard information that are not needed for runtime operation, i.e. enum values, type defs, local variable names, line numbers, etc.

Class methods registered as global functions

This could be used to register for example singleton methods so that the script call them just like any other global function. Internally the VM would use the registered object pointer to call the method.

For singletons this can easily be done through wrappers as the object pointer can be resolved through a global variable or a static method to retrieve the singleton pointer.

Where the class method is not for a singleton it might be a little more difficult to solve with wrappers as it will be difficult to determine the object pointer. Because of this the best solution may actually be to implement this support in the core library after all.

Improve the way the compiler determines use of temporary variables

I've fixed many bugs in the compiler that are similar to each other but appear in different situations. The compiler is not good at verifying that a temporary variable isn't in use when it allocates one for expression evaluations. I'll have to redesign the way the compiler handles temporary variables to make it more robust.

Separate compiler from VM

The idea is that the compiler and the VM should be separate components, that can be used individually. This would make it possible to write a different compilers for the same VM that supports a different syntax. It would also be possible to embed only the VM in the application, without the compiler, in this case the application would use precompiled bytecodes instead.

Rename asIScriptContext to asIScriptThread (or asIExecutor)

I'm thinking about renaming the context interface to better show what it is. The current context class is not much more than a script thread anyway at the moment. This may be done before the context redesign mentioned below.

A better name may be asIExecutor, since the context really is that, an interface for executing script functions.

Context redesign

The context as it is now will be removed, and replaced by a new context interface and a thread interface.

The context holds the environment in which threads are executed. Thus it will keep track of global variables and memory allocations, shared between threads.

A thread will only control the execution of a script, i.e. hold the call stack while it is running. Thus it will not be necessary to keep the call stack in memory when it is not used.

Unless, non-shared global variables are implemented, this redesign is pretty useless as the contexts will not hold anything.

Registerable context properties

Requires: Shared/non-shared global variables

A context property is a non-shared global variable registered from the application. After creating the context, the context property must also be set, otherwise a null pointer exception will occur.

I'm not sure if this is actually useful, so this will probably not be implemented.

Support debug only functions

I'd like to support registration of functions like assert() that is only used in debug mode. In release mode the function will be removed, together with the argument expression.

dynamic inclusion of script code

It may be interesting to be able to include script codes for execution inside functions, dynamically at run-time. The script code should be injected into the script stack so that it can access the variables in the function, much like a run-time generated macro. Idea by Dave Krusu.

Persistent script states

It would be great if it was possible to save/load the script state, including the context stack. This is difficult to do, but I believe it can be done. It would require registered types to have a serialization behaviour.

Compile to native code JIT

This would definitely speed up the execution speed. I do not want to loose functionality though, such as the ability to set breakpoints, co-routines, etc. A discussion on the subject with interesting ideas for implementation.

Precompiled bytecode

  • Make the precompiled bytecode less dependent on the engine configuration

    It may be possible to make the precompiled bytecode less dependent on the engine configuration if we store more information while saving the bytecode. While loading the bytecode the engine should adjust it to adapt to the current engine configuration. This means that it shouldn't be a problem with adding new functions and global variables, reorganizing existing ones. Of course, if a function/variable that the script uses has been removed, or changed type, the load will fail. It may even be possible to have the loading adjust access to class members, though that is a more difficult.

    The advantage of this is that it would be easier to write a common script compiler, without having to share all the code with the application that will use the scripts.

  • Platform independent bytecode

    With independent bytecode it would be possible to compile a script on one platform, save the bytecode, and the load the bytecode for execution on another platform.

    This is something that I want to do someday. Though I'm not sure how well it will work with AngelScript being so closely tied to C++. Pointers wouldn't work for example, as that is too low-level. The boolean type is also not equal on all platforms.

    Things that are currently making the code platform dependent:

    • endianess
    • pointer size
    • alignment/packing of class members
    • alignment of variables on the stack
    • size and value of boolean type

    Could perhaps have a an engine property to tell the compile to produce some platform independent intermediate bytecode, rather than the bytecode that the VM will execute. When loading this pre-compiled independent intermediate bytecode, the loader would need to convert it to the final platform dependent bytecode.

Allow script classes to inherit from application classes

Investigate the possiblity of allowing script classes to derive from application registered classes. May work if the application class derives from the internal asCScriptStruct class.

Some info


Script language

Add support for final class methods, and final classes

Suggestion by Bismuth

Allow return of reference

Currently script functions don't permit returning references, though application registered functions do.

The script language should allow this too, but it must take care to make sure the reference is valid.

  • Must not be allowed to return reference to local variable
  • Must not be allowed to return reference to parameter passed by value
  • Must not be allowed to return reference to temporary object
  • Must not be allowed to return reference returned from a class member of a local variable
  • Must be allowed to return reference to global variable
  • Must be allowed to return reference to class member
  • Must be allowed to return reference to input reference parameter (only if the returned reference is const, as the input parameter is not supposed to be modified)
  • Must be allowed to return reference returned from a global function
  • Must be allowed to return reference returned from class member of a non-local variable
  • Must be allowed to return reference to in/out parameter
  • Should it be allowed to return reference to output parameter? The reference is to a temporary value so what would it mean?

Reflection

It should be possible to register methods/functions with the engine that add support for reflection.

It is already possible to implement enumeration of types, variables, functions, etc, and to create instances of new classes.

It's possible, but complicated, to implement an 'invoke' function that calls an arbitrary function/method with arbitrary arguments. To support this I need to implement support for variable argument lists.

It's not yet possible to dynamically create new functions from within the scripts. For this to be possible the engine needs to be able to compile single functions in a module, and have support for function pointers.

Treat all reference types by handle

Related to: language references

Modern languages such as D, Java, C#, and most script languages treat all reference types by handle, i.e. all variables of these types are only handles to instances, and all functions parameters are also by handle.

The one thing you lose with this is an explicit assignment operator for copying content as the assignment operator will perform a handle assignment rather than copying the content of the object. (Though it may be possible to create another operator for this.)

The advantage of implementing this would be a cleaner language syntax, in that the @ can be completely removed, thus also simplifying the compiler.

I haven't decided whether I really want to implement this, but I don't think it would be too difficult. If I decide to implement this, it would be for version 3.0.0 together with the change to the parameter references.

Note, AngelScript already supports implicit handle types by turning on the engine property asEP_ALLOW_IMPLICIT_HANDLE_TYPES.

Improved algorithm for finding best matching function

The algorithm for determining the best match for function overloads can be improved. For example 'void func(a &in, a &in)' and 'void func(const a &in, const b &in)' is not resolved for a call to 'func(_a, _b)'. It is not resolved because _a is a non-const reference, which matches exactly with the first function but not the second, thus the compiler doesn't even attempt to match the second function, even though it is actually a match.

Initialize all variables to 0 by default

If I initialize all variables to 0 by default then I could simplify the code somewhat. There would no longer be a need to check if a variable is used before it is initialized. It would impact run-time performance slightly, though not always negatively since I'm already initializing object variables to 0 via a loop. With the change the code could simply initialize the entire function block on the stack to 0 with a much faster implementation.

It would also be easier on the script writer I believe.

If I do this, I have to remember that variables should not just be initialized to zero when entering a new function. The variables must be initialized to zero every time a new scope is entered, e.g. each iteration of a loop.

This might be solved by using push and pop to handle the scope. When push is used to increase the stack space it will be incremented with zeroes.

I may be able to do this initialization only if the compiler discovers that the variable is used without being initialized first. That would avoid unecessary bytecode being generated, and thus not impact performance.

Improve function pointers

Add the function type. The function type is a type that can store any function pointer, but cannot be invoked directly. The caller must first do a ref_cast to the wanted function definition, and then invoke that.

Taking the address of a function must be able to resolve function overloads automatically by checking the type of the variable where the address will be stored.

It must be possible to declare function definitions that use types declared below it in the script.

Implement try/catch statements in the scripts

The catch statement will allow the script to recover from an exception. The type of exception that was thrown can be accessed from the application, if it wishes to implement such a function.

Support for typeof() and sizeof()

I'll implement these one day.

Global statements

It should be possible to write statements in the global scope. These statements will be executed at build time. They will be executed in the order they were declared. If multiple script sections are included, then the statements in each section will be included in the order the sections were added.

This also means that global variables will be initialized in the order they are declared, and that a global variable doesn't see variables declared after it.

Functions and class declarations will still be seen from above themselves. This also means that if a function is called from the top of the file, it can access variables that haven't been fully initialized yet (it will only see the default value). In case of accessing object variables, this will result in a null pointer exception.

Change script language references

Add the alternative syntax for output references: 'out type parmname'. Turn off the current script language references via an engine property, so that they can be turned on again. Application functions should still be registered as they currently are, with &in, &out, etc.

See also: Parameter references

Improve multi-line strings

Question: should I have any processing to make the line breaks the same on all platforms? I.e. should any combination of \r, \n, \r\n, \n\r be translated into a single \n character? We probably need to make this uniform so that the resulting string will be equal on all platforms. Heredoc strings currently doesn't translate the line breaks.

Static arrays

Related to: dynamic arrays

Allow use of static arrays in the scripts, e.g. int ar[3]. These will be directly compatible with C++ arrays. They will not be objects, so it will not be possible to store a handle for a static array, but they can be passed by reference to functions.

It should be possible to assign part of a bigger array to a smaller array, e.g.:

int a[10], b[3];
b = a[3..5];     // copies index 3, 4, and 5 to the array in b

Look at the D language for more ideas on arrays.

The static array types should be treated as an easy way to declare multiple variables that can be accessed through an index.

The static array type can have a size that is defined at run time, e.g. with a parameter name. In this case the memory for the array is allocated on the heap, plus a hidden variable that gives the size of the array. The same thing happens if the size of the array is fixed, but too large, e.g. larger than 100 elements.

The static array type will only be implemented when the dynamic array type has been removed from the language.

When passing a static array by parameter, or returning it, the size of the array must be fixed. That way it is not necessary to pass the size of the type as a separate variable.

default argument value

Allow declaration of functions with default argument values.

Ex: void func(int arg1, int arg2 = 0);

switch statements with string constants for case labels

It would be interesting to allow switch statements with string constants. I could make it use a binary search scheme to optimize the call.

Allow calling constructor from within constructor

I'd like to allow a script class constructor to call one of the other script class constructors, so that the code can be better reused. The compiler needs to keep track of which constructors calls which, so that endless loops won't be created.

Default initialization of class members

Thomas Cowell suggested the following syntax for initializing class members:
class MyClass
{
  int m_int = 123;
  string @m_str = @do_something();
}

  • These initializations would be done before the constructor.
  • If one member variable is initialized with the value of the other then the other must be initialized first (just like how global variables are initialized). Allowing out-of-order initialization may be more confusing than helpful.
  • Maybe these initializations should only permit constant expressions. Should the initialization expression be allowed to call methods on the class? What would happen if the method accesses the member variables? All member variables could be set to 0 before they are initialized, if a member object is accessed before it is initialized a null pointer exception would be thrown.

    I haven't decided yet if I really will implement this.

    Data structures

    The struct will come back to AngelScript. Now it will be used to allow the scripts to declare the exact memory layout of a structure. There will be no hidden members of a struct, and the packing can be controlled exactly. This will make the struct compatible with C++ structs, and allow for easier data manipulation in complex memory layouts, such as data files, etc.

    It will not be possible to store a handle to a struct, nor will the struct be able to inherit from another class or struct.

    I'm not so sure about the usefulness of this anymore.

    Reference types must not be allowed in data structures. Handles can be safely used in the structures though.

    To guarantee safety in the scripts the implicit copy constructor of a value type must have certain restriction. This is to guarantee that the constructor itself doesn't destroy the structure that is being copied before it is time. Should I prevent the user from implementing a copy constructor, or should I simply automatically generate a copy constructor that will be used for the implicit calls?

    Return of pointers

    Implement pointer support again. Now with full support for access, type casts, etc.

    Even though pointers cannot be used in an environment where security is wanted, they are still very useful when the scripts are written for prototyping.

    Namespaces

    Related to: class prototypes

    With the addition of namespaces the scripts that previously had to be compiled in separate modules, can now be compiled in one module and still use the same names. The benefit for this is the better reutilization of common functions.

    Modules will still exist, of course.

    Implement class methods outside the class declaration

    Related to: namespaces

    Yes, I intend to allow implementation of class methods outside the class, just as in C++. I just haven't gotten around to it yet.

    Improve typedef

    Allow typedef to be used with any type, not just primitives.

    The asCDataType object that defines a typedef should have a subtype to the true type. All functions that ask what kind of type the typedef is should return what the subtype returns.

    Variable argument count

    I want to be able to support the ... parameter declaration. I will not implement it as loosely as C does it. Instead the function will receive the argument count, and be able to access both the value and the type of the value. This will make the use of the ... in scripts just as safe as any other function.

    The script will have to add an extra keyword for parameters if the argument is support to be a return value, something like: func( (out)arg );

    String modifier to turn on/off escape sequences

    Strings prepended with a backslash should not translate escape sequences. This is perfect for those strings where backslashes commonly appear, such as file paths and regular expressions. Example: \"Hello\x20there" won't be translated to "Hello there".

    Removing parameter references from script language

    I'm thinking about abolishing the use of parameter references from the AngelScript language (unless the option to allow unsafe references is turned on). The script language will still permit output parameters, but would probably be renamed to just out without the ampersand. The language would also still allow passing parameters via object handles (for those types that supports it). What would be removed is &in and &inout.

    Doing this would make the language much more consistent in the way it works, thus easier to understand for the script writers. The impact in performance and to the application developers shouldn't be too big.

    AngelScript would still permit the application to register functions that take parameters by reference, but only were it can be translated to the permitted AngelScript syntax. A const type & could just as well be sent by value, and a type & would be translated to either type @ or out type.

    This is obviously a bit of a step backwards, so it's not a decision to be taken lightly. If I do it, I'll probably change the version number to 3.0.0. A replacement should also be available at the time this is implemented, e.g. the option to turn on unsafe references, and/or allow use of pointers.

    static declarations

    I may implement support for static declarations, that is static variables, static class members, etc.

    Shared/non-shared global variables

    Requires: Context redesign

    A global variable can be marked as shared between contexts, i.e. all contexts referencing the same module will access the same memory for that variable.

    A non-shared global variable is local to the context, i.e. each context has it's own instance of the variable.

    By default the global variables are shared.

    By allowing the scripts to declare non-shared global variables, the application will have a difficult time to control the memory needed for each context. Due to this I may not implement this feature.

    If I can think of a way to instanciate the global variables only for those contexts that actually need them, then I may consider this feature again.

    L post fix to indicate 64bit integer constant

    By default the script compiler assumes a 32bit constant, unless the number is larger than 32bit. In some operations it might be convenient to be able to define the constant as 64bit by appending an L to the number. Currently the same task has to be handled by explicitly casting to the corresponding 64bit type, i.e. int64(0) or uint64(0).

    Add-ons

    Variant type + Improved any type

    Requires: Cast behaviours
    Related to: variable type

    The 'any' type will not be substituted for the 'var' type. The 'any' type is a generic container, whereas the 'var' type is a generic primitive capable of storing and working with any primitive type.

    The 'var' type should have all the mathematical operators with overloads for all primitive types (+ the string type). It should also have methods like asString, asInt, asDouble to convert the variant to a primitive.

    The 'any' type could perhaps be improved to allow storing index values by implementing the index operator.

    CFile

    The CFile object should have the ability to read/write primitives. It must also be able to handle little-endian and big-endian formats.
    // The integer functions can read 1,2,4, and 8 byte integers
    int64  ReadSignedInt(uint byteSize);
    uint64 ReadUnsignedInt(uint byteSize);
    float  ReadFloat();
    double ReadDouble();
    
    void   SetEndianFormat(bool littleEndian);
    
    // Returns true if successful
    bool   WriteSignedInt(int64 value, uint byteSize);
    bool   WriteUnsignedInt(uint64 value, uint byteSize);
    bool   WriteFloat(float value);
    bool   WriteDouble(float double);
    

    Bit packer

    A bit packer object would be used to extract binary data from a string buffer. It will have methods for unpacking all primitive types, and also arrays of these types. It can also have a method for unpacking generic types, where the method takes a reference to a variable type (?), then determines the properties of this type and unpacks each of them. If the variable type cannot be unpacked (then an exception will be thrown).

    Auto wrapper for calling script functions

    Now that we have automatic wrappers for the generic calling convention, it ought to be possible to write automatic wrappers for calling script functions too.

    Of course, since most applications have their own way of creating the contexts, and scheduling the executions. Perhaps it's better to just have automatic pushing of arguments on the context stack.

    asDECLARE_ARG_PUSHER2(arg_pusher, float, string);
    
    // Generates
    void arg_pusher(asIScriptContext *ctx, float a1, string a2)
    {
      new(ctx->GetAddressOfArgLocation(0)) float(a1);
      new(ctx->GetAddressOfArgLocation(1)) string(a2);
    }
    

    Context manager

    The context manager should handle pooling of script contexts. It should also provide functionality for allowing one script to wait for another, etc.

    The context manager should also implement intelligent calls to the garbage collector.

    The context manager should also permit debugging, by setting breakpoints and step-by-step execution.


    Things that won't make it

    Or is at least not considered at this moment.

    Support initialization list for members in constructors

    The initialization of object members in constructors can be made much more efficient if initialization lists are supported. This will avoid first initializing the members with their default constructors and then overwriting that with other values.

    ClassTest::ClassTest() : Member1(0), Member2(3) {}

    I don't think I'll implement this, since it is a rather obscure syntax, and not really necessary. Especially after all reference types will be treated as handles.

    expression separator with ,

    In C++ this is mostly seen in for loops where you want to declare and iterate over more than one variable together.

    Add callback for context creations

    It shall be possible for an application to register a callback function that will be called each time a new context is requested. This is useful for applications that rely on context user data and/or line callbacks. With this change they will be able to set these on contexts created and used internally by the engine, e.g. during Build to initialize global variables, during array resize to call class constructors, in CreateScriptObject to call class constructors, and also ExecuteString.

    Drawback: The ability to hook up line callbacks for internally used contexts may lead to the attempt of suspending those contexts, which may not be such a good idea. The code that is invoking the contexts may not be resumable, for example if the context is invoked to initialize an array element as part of the resizing of an array of script classes. It would be necessary to block the ability to suspend contexts used for this purpose, but that would in turn kind of defeat the purpose of having a line callback in the first place.

    This idea has been discarded in favour of reusing existing contexts to call these functions. Where currently a context is created internally the application will be able to supply the context it wishes to use and thus be able to fully control the execution.

    Pre/Post condition contracts

    Sometime in the future support for pre/post condition contracts may be added.

    Dynamic binding of global variables between modules

    Just like functions can be imported between modules it would be possible to implement dynamic binding of global variables between modules. I'm not convinced that this is something useful though.

    Support for registration of classes with virtual base classes

    I'll probably never implement this support. It is highly platform dependent and would be difficult to support on all platforms. Besides, it is something that is very rarely used in C++ programs, and especially games and other high performance applications, due to the extra overhead it adds to method calls.

    Implicitly called functions

    Description. I don't think this would bring any advantages to AngelScript.

    Allow registering a behaviour for the not operator

    Permit applications to register behaviours for the not operator. Just like it is currently done for the negate operator. Suggested by Gilad Novik.

    Do I really want to allow this? What would it mean? AngelScript doesn't allow implicit conversions of types to bool. Why should it allow a non boolean type to use the 'not' operator?

  • support the site
    make a donation

    link to site


    sponsor links
    your site here