|
|
Work in progressYou can always find the latest version of AngelScript in the SVN on SourceForge.net. Download by pointing your SVN 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. You can also browse the repository directly. Version 2.13.1 WIP - 2008/07/20
Known bugs
Changes planned for later versionsThese 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:
planned for next release:
Multithread supportAdd 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.Improve C interfaceCode for improving the C interfaceAdd meta data supportChet Simpson sent me the code for this. Basically it allows developers to add meta data to the script functions, variables, and classes. The script engine itself ignores this meta data, but the application can use it to, for example find variables that the script writer want to expose in a form for editing, or to find functions that have specific meaning such as creating objects.
Priority: high Improvements to APII need an asIModule interface. All script module methods should be moved from the engine interface to this new interface.asIScriptFunction and asIScriptObject needs to have AddRef and Release so the application can hold references to the function. Much of the engine methods can be moved to asIScriptFunction and asIScriptObject interfaces. Priority: high Improve compiler messagesThe error message when the compiler cannot match a function call is too generic. It needs to be improved to give more specific details, e.g. is the name incorrect, is the number of arguments incorrect, are the multiple matching functions, etc. Suggestion by Scott Bean from Activision.Priority: high Improved documentationThe documentation needs to be improved in several places. Here are some of the things I'll try to do:
Priority: high Initialize all variables to 0 by defaultIf 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.
Priority: high Dynamic global variables and functionsAll functions and global variables should be stored in reference counted objects.When a script is compiled the module holds a reference to each of the functions and global variables. A function or global variable can be removed from the scope of the module, this however doesn't necessarily mean it will be destroyed, as another function may still be referencing it. If a new function is compiled in the module, it won't see these removed functions and global variables though. Likewise new global variables and functions can be dynamically introduced in the module scope, which will then allow future functions to be compiled which references these functions. The actual compiler may use this feature when finding matching functions. It must then be possible to declare a function without actually implementing it. This will create the function object but won't define its function body.
Priority: high Improved memory management for value typesNow 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. Priority: highBetter validation of registered functionsI 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
Priority: high Add a way to obtain the function id of the system function being calledIt 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.
Priority: high Remove ambiguities with object handle expressionsWhen doing handle assignments it may be better to require explicitly taking the handle to the rvalue. Otherwise it is too easy to forget to add the handle for the lvalue and get a value assignment instead of a handle assignment, which may not be easily spotted. Do I need to add similar requirements in other expressions involving handles, e.g. comparisons, or function arguments?Handle assignments should require explicitly taking the handle to the lvalue. The rvalue can then be implicitly converted to a handle.
Priority: high Comparison operatorConsider implementing the comparison operator that perl has: <=>. This operator returns -1, 0, or 1 depending on the relation between the values. The script compiler could automatically derive the other comparison operators from that. Having this operator in the language would simplify the interface, as the application could register this function and all others would work. It would also more easily permit the script writer to implement comparison operators for script declared classes. It would also simplify the implementation of the CompareScriptObjects method.Note, it may still be interesting to allow the application to register the more specific comparison operators, as a form of optimization. If only the equality operator is registered then the function will return either 0 or 1 depending on whether the values are equal or not. To be able to do all comparisons, two comparisons must be registered, "less than" and "equal". The function will first compare with "less than", and if not less, it will compare with "equal".
Priority: high All script code should be resumableCurrently 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.
Priority: high Improved support for complex types in native calling conventions on PPCPPC 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.
Priority: high Improving context interface for calling script functionsI 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.
Priority: high Function pointersAllow use of function pointers. I think I'll require a typedef to define the signature of the function, which will simplify the code.A function pointer in the script will be a function id from the script engine, so you won't be able to pass in a pointer to a C++ function directly. Though a function id to a registered function is allowed, so indirectly it is pointing to a C++ function. Even though script functions can be shared between modules, each have their own unique global id. Which means that the global function id, must hold information about both the module and the local function id. Module B is cloned from Module A. The function test() will have the same local id in both Module A and B. The global id however is different. Inheritance for classesI'll implement single inheritance for classes.
Allowing script classes to inherit from arbitrary registered classes without requiring a specific protocol probably don't work. Though if possible, I'd like to implemement this. One problem is if a script class inherits from the registered class, then a pointer to the derived class is passed to an application function that expects a pointer to the C++ class for storage. The application will then store the pointer to the C++ class, which in itself is ok, but the AngelScript garbage collector won't know of this, since it relies on reference counting on the script class to determine if the object is alive or not. Likewise the application will have a difficult time to know if the object pointer is a true C++ class or a script derived class. If the application calls delete on the pointer, it will break, since the pointer is not to the real memory block, nor will the script class's destructor be called. I don't think I'll implement multiple inheritance. The interfaces are already capable of handling most of the uses for multiple inheritance. Virtual inheritance most certainly wont be implemented, as that is a concept way too complicated and almost never used so it's just not worth it. Implement class methods outside the class declarationRequires: scopeRelated 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 cast behavioursIt must be possible to tell AngelScript which cast behaviour may be used for implicit casting by the compiler. asBEHAVE_VALUE_CAST_IMPLICIT and asBEHAVE_REF_CAST_IMPLICIT must be implemented to support this. asBEHAVE_FACTORY/asBEHAVE_CONSTRUCT should never allow implicit casts.
All explicit value casts should be made with: type(expr). All explicit ref casts should be made with: cast
Priority: medium/high
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.
Priority: medium/high
See also: Parameter references
Priority: medium/high
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.
Priority: medium/high
Priority: medium
The application should only have to inform the exact C++ type, if it wants to application functions that passes the type by value, using native calling conventions. That is, make all asOBJ_APP_XXXX flags optional.
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?
Priority: medium
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?
Priority: medium
Priority: medium
The parser should be able to handle syntax like: void Scope::Func(). With this I can modify RegisterObjectMethod() and GetMethodIDByDecl() to no longer need the extra parameter of the object type, since it would be part of the signature. It will also permit declaration of the script class methods outside the script class declarations. It will also facilitate the addition of namespaces. Suggestion by Gilad Novik.
Priority: medium
Priority: medium
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.
Priority: medium
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.
Priority: medium
Priority: medium
Priority: medium
It should be possible to assign part of a bigger array to a smaller array, e.g.:
Look at the D language for more ideas on arrays.
I want the application to be able to register template classes, or something similar. This should then substitute the internal dynamic array objects, which I don't feel work too well.
It will be something like:
The script will then use it like:
The application should then be able to overload the registered generic template array object for specific implementation.
The advantages with this is that the application will have complete control over the implementation of these objects, and I can get rid of the internal array object which isn't as flexible as I want it to be. Another advantage is that these template classes can be extended to other structures as well, e.g. maps, etc.
Add methods like: push_back(), push_front(), pop_back(), pop_front(), reserve(), insert(), erase(), etc. Suggestion by mushr00m.
I also need a better way of setting the initial size for multidimensional arrays, and maybe for resizing all the sub arrays with one call.
Once static arrays are implemented and generic containers are supported, I think I want to move the dynamic arrays out of the engine and make them into add-ons. It should be possible to register a generic array type that can hold any type of elements. This one would work exactly as the built-in asCArrayObject does today. Once the array object is registered from the application, the application decide the exact interface for the array objects, and can make all array types support the same interface without any problem.
Priority: medium
Ex: void func(int arg1, int arg2 = 0);
Priority: medium
Priority: medium
Priority: medium
ClassTest::ClassTest() : Member1(0), Member2(3) {}
Priority: medium
Priority: medium
I haven't decided yet if I really will implement this.
Priority: medium
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.
Priority: medium
If two different modules declare the same interface, both declarations should share the same type id. With that it will be possible to transfer an object from one module to another and still allow the script interact with it properly through the interface.
Priority: medium
Add support for importing class definitions from other modules, so that a class can be implemented in one module yet used in another.
Priority: medium
I'm thinking about adding support for UTF-8. This works well as it should allow current applications to work without changes, and also applications that want to use unicode should be able to do so without much changes. UTF-8 has the nice property of having all the characters that the compiler recognizes in one byte just as a normal ASCII code.
The tokenizer can raise a compiler error if it encounters a character >= 128 outside comments or text strings. And the text strings with unicode characters can be sent to the string factory normally.
Obviously support for unicode or not should be an engine property that can be dynamically set by the application.
Priority: medium
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.
Priority: medium
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.
Priority: medium
Priority: medium
Priority: medium
Priority: medium
Priority: medium
Suggestion by Dentoid.
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.
Priority: medium
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.
Priority: medium
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.
Priority: medium/low
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.
Priority: medium/low
Priority: medium/low
Priority: low
Priority: low
Priority: low
Priority: low
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.
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.
Priority: low
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.
Priority: low
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 );
Priority: low
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.
Priority: low
This will allow the application to register a couple of functions to
manipulate properties. An example that shows the usefulness of this is: Say you've registered HWND as a type, and you want to let the script change the title of the window. You can either register the Set/GetWindowText() as methods which will be explicitly called, or you can register a get/set property called text, which the script can access just like any other object property.
I need to investigate the complications of this. What happens for example
if a property is passed by reference to a function that is supposed to update it? Since the get/set property isn't a real reference this has to be checked for.
Priority: low
Priority: low
Priority: low
Priority: low
Priority: low
Priority: low
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.
Priority: low
Priority: low
Priority: low
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.
Priority: none
Priority: none
Priority: none
Priority: none
Priority: none
I'll possibly rename the any type to 'var', which I feel is a better name.
I want this type work more like the variants of javascript or VBScript, i.e.
you should be able to assign any type to it, and then perform operations on it.
All the operators should work, and the meaning will depend on the contents of
the any type.
It may not work for method calls, as that requires compile time knowledge of
the type. So for objects, the type will only work as a container, but for
primitives the type should work just fine. It will also work for string
concatenations etc.
Maybe I'll make the any type allow storage of multiple values as well, simply by allowing use of the index operator to access list or hash members. Or maybe I'll create another type for this.
The script dictionary class should be able to work with either of the two.
|
|