/source/core/XSRuntime.c
C | 518 lines | 332 code | 113 blank | 73 comment | 90 complexity | 4535ed52357b165eb23b86e07a3895c1 MD5 | raw file
- /*******************************************************************************
- * Copyright (c) 2011, Jean-David Gadina <macmade@eosgarden.com>
- * Distributed under the Boost Software License, Version 1.0.
- *
- * Boost Software License - Version 1.0 - August 17th, 2003
- *
- * Permission is hereby granted, free of charge, to any person or organization
- * obtaining a copy of the software and accompanying documentation covered by
- * this license (the "Software") to use, reproduce, display, distribute,
- * execute, and transmit the Software, and to prepare derivative works of the
- * Software, and to permit third-parties to whom the Software is furnished to
- * do so, all subject to the following:
- *
- * The copyright notices in the Software and this entire statement, including
- * the above license grant, this restriction and the following disclaimer,
- * must be included in all copies of the Software, in whole or in part, and
- * all derivative works of the Software, unless such copies or derivative
- * works are solely in the form of machine-executable object code generated by
- * a source language processor.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ******************************************************************************/
-
- /* $Id$ */
- /*!
- * @file XSRuntime.c
- * @brief Implementation of the runtime functions
- * @author Jean-David Gadina <macmade@eosgarden.com>
- * @author St?phane Cherpit <stef@eosgarden.com>
- */
- #include "XS.h"
- #include "core/__private/__XSRuntime.h"
- #include "core/__private/__XSMemory.h"
- #include "core/__private/__XSMemoryDebug.h"
- #include "eos-skl/eos-skl.h"
- /*!
- * define __XS_RUNTIME_CLASS_TABLE_SIZE
- * @brief Default allocation size for the runtime class table
- */
- #define __XS_RUNTIME_CLASS_TABLE_SIZE 1024
- /*!
- * define __XS___XS_RUNTIME_INIT_CHECK_INIT_CHECK
- * @brief Checks if the runtime has been initialized
- * @details This macro will produce a fatal error if the runtime has not been initialized.
- */
- #define __XS___XS_RUNTIME_INIT_CHECK_INIT_CHECK if( __xsruntime_inited == NO ) { XSFatalError( "Error: the runtime has not been initialized\n" ) }
- /*!
- * @var __xsruntime_inited
- * @brief Whether the XSFoundation runtime has been initialized
- */
- extern BOOL __xsruntime_inited;
- /*!
- * @var __class_table
- * @brief The runtime class table
- */
- extern XSRuntimeClass * __xsruntime_class_table;
- /*!
- * @var __class_size
- * @brief The allocated size of the runtime class table
- */
- extern size_t __xsruntime_class_size;
- #ifdef _WIN32
- extern __declspec( thread ) XSObject __xsruntime_current_object;
- extern __declspec( thread ) XSMethod * __xsruntime_caller;
- extern __declspec( thread ) XSMethod * __xsruntime_previous_caller;
- #elif ( defined __MACH__ )
- extern pthread_key_t __xsruntime_current_object;
- extern pthread_key_t __xsruntime_caller;
- extern pthread_key_t __xsruntime_previous_caller;
- #else
- extern __thread XSObject __xsruntime_current_object;
- extern __thread XSMethod * __xsruntime_caller;
- extern __thread XSMethod * __xsruntime_previous_caller;
- #endif
- /*!
- * @var __class_count
- * @brief The number of registered classes in the runtime class table
- */
- extern size_t __xsruntime_class_count;
- XSClassID XSRuntime_RegisterClass( const XSClassInfos * const cls )
- {
- __XS___XS_RUNTIME_INIT_CHECK_INIT_CHECK
-
- if( __xsruntime_class_size == 0 )
- {
- XSDebugLog( XSDebugLogLevelDebug, "Allocating space for the class table" );
-
- if( NULL == ( __xsruntime_class_table = ( XSRuntimeClass * )calloc( sizeof( XSRuntimeClass ), __XS_RUNTIME_CLASS_TABLE_SIZE ) ) )
- {
- fprintf( stderr, "Error: unable to allocate the runtime class table!\n" );
- exit( EXIT_FAILURE );
- }
-
- __xsruntime_class_size += __XS_RUNTIME_CLASS_TABLE_SIZE;
- }
-
- if( __xsruntime_class_count == __xsruntime_class_size )
- {
- XSDebugLog( XSDebugLogLevelDebug, "Reallocating space for the class table" );
-
- if( NULL == ( __xsruntime_class_table = ( XSRuntimeClass * )realloc( __xsruntime_class_table, sizeof( XSRuntimeClass ) * ( __XS_RUNTIME_CLASS_TABLE_SIZE + __xsruntime_class_size ) ) ) )
- {
- fprintf( stderr, "Error: unable to re-allocate the runtime class table!\n" );
- exit( EXIT_FAILURE );
- }
-
- __xsruntime_class_size += __XS_RUNTIME_CLASS_TABLE_SIZE;
- }
-
- XSDebugLog( XSDebugLogLevelDebug, "Registering class: %s", cls->className );
-
- __xsruntime_class_table[ __xsruntime_class_count ].classInfos = ( XSClassInfos * )cls;
-
- return ++__xsruntime_class_count;
- }
- void XSRuntime_BindMethodToClassID( XSClassID classID, void ( * func )( XSObject __self, ... ), const char * name, XSModifier modifiers, void ( * casterInit )( XSObject _self ) )
- {
- XSRuntimeClass * cls;
- XSMethod * method;
-
- if( classID > __xsruntime_class_count )
- {
- return;
- }
-
- cls = &( __xsruntime_class_table[ classID - 1 ] );
-
- if( cls->methodCount == cls->methodSize )
- {
- if( NULL == ( cls->methods = realloc( cls->methods, sizeof( XSMethod ) * ( cls->methodCount + 100 ) ) ) )
- {
- fprintf( stderr, "Error: unable to re-allocate the class methods table!\n" );
- exit( EXIT_FAILURE );
- }
- }
-
- method = &( cls->methods[ cls->methodCount++ ] );
- method->name = ( char * )name;
- method->modifiers = modifiers;
- method->func = func;
- method->casterInit = casterInit;
- method->ownerClass = cls;
- }
- XSMethod * XSRuntime_GetMethod( XSObject object, const char * name )
- {
- XSClass cls;
-
- if( object == NULL )
- {
- return NULL;
- }
-
- cls = XSRuntime_GetClassForObject( object );
-
- if( cls == NULL )
- {
- return NULL;
- }
-
- __XSRuntime_SetCurrentObject( object );
-
- return __XSRuntime_FindMethod( cls, ( char * )name );
- }
- XSObject XSRuntime_GetCurrentObject( void )
- {
- #ifdef __MACH__
-
- return pthread_getspecific( __xsruntime_current_object );
-
- #else
-
- return __xsruntime_current_object;
-
- #endif
- }
- XSMethod * XSRuntime_GetCaller( void )
- {
- #ifdef __MACH__
-
- return pthread_getspecific( __xsruntime_caller );
-
- #else
-
- return __xsruntime_caller;
-
- #endif
- }
- XSMethod * XSRuntime_GetPreviousCaller( void )
- {
- #ifdef __MACH__
-
- return pthread_getspecific( __xsruntime_previous_caller );
-
- #else
-
- return __xsruntime_previous_caller;
-
- #endif
- }
- XSObject XSRuntime_CreateInstance( XSClassID typeID )
- {
- XSRuntimeClass * cls;
- size_t size;
- XSInstance o;
- //size_t i;
-
- __XS___XS_RUNTIME_INIT_CHECK_INIT_CHECK
-
- if( typeID > __xsruntime_class_count || typeID == 0 )
- {
- return NULL;
- }
-
- cls = &( __xsruntime_class_table[ typeID - 1 ] );
- size = cls->classInfos->instanceSize;
- o = XSAllocInstance( size, typeID );
-
- if( o != NULL )
- {
- o->__class = cls;
-
- /*for( i = 0; i < cls->methodCount; i++ )
- {
- if( cls->methods[ i ].casterInit != NULL )
- {
- cls->methods[ i ].casterInit( o );
- }
- }*/
- }
-
- return ( XSObject )o;
- }
- XSObject XSRuntime_CreateInstanceOfClass( XSClass cls )
- {
- XSClassID classID;
-
- if( cls == NULL )
- {
- return NULL;
- }
-
- classID = XSRuntime_GetClassIDForClass( ( XSClass )cls );
-
- if( classID == 0 )
- {
- return NULL;
- }
-
- return XSRuntime_CreateInstance( classID );
- }
- XSObject XSRuntime_CreateInstanceOfClassWithName( const char * name )
- {
- size_t i;
- XSRuntimeClass * cls;
-
- if( name == NULL )
- {
- return NULL;
- }
-
- for( i = 0; i < __xsruntime_class_count; i++ )
- {
- cls = &( __xsruntime_class_table[ i ] );
-
- if( strcmp( cls->classInfos->className, name ) == 0 )
- {
- return XSRuntime_CreateInstance( i + 1 );
- }
- }
-
- return NULL;
- }
- const char * XSRuntime_ObjectDescription( void * ptr )
- {
- XSString description;
- XSString str;
- __XSMemoryObject * o;
- XSClass cls;
-
- if( ptr == NULL )
- {
- return "<XSObject: nil>";
- }
-
- if( XSRuntime_IsInstance( ptr ) == NO )
- {
- return "<XSNotAnObject>";
- }
-
- o = __XSMemory_GetMemoryObject( ptr );
- cls = XSRuntime_GetClassForClassID( o->classID );
- //str = XSNew( XSString );
- //XSAutorelease( XSCall( str, Init ) );
- str = XSAutorelease( XSCall( XSString, XSNew( XSString ), Init ) );
-
- //XSApply( str, AppendFormat, ( char * )"<%s: %p>", cls->classInfos->className, ptr );
- XSApply( void, str, AppendFormat, ( char * )"<%s: %p>", cls->classInfos->className, ptr );
-
- if( cls->classInfos->toString != NULL )
- {
- description = cls->classInfos->toString( ptr );
- //XSApply( str, AppendFormat, ( char * )" [ %s ]", XSCall( description, CString ) );
- XSApply( void, str, AppendFormat, ( char * )" [ %s ]", XSCall( char *, description, CString ) );
- }
-
- //return XSCall( str, CString );
- return XSCall( char *, str, CString );
- }
- BOOL XSRuntime_IsInstance( void * ptr )
- {
- __XSMemoryObject * o;
-
- if( ptr == NULL )
- {
- return NO;
- }
-
- o = __XSMemory_GetMemoryObject( ptr );
-
- if( o->classID > 0 && XSRuntime_GetClassForClassID( o->classID ) != NULL )
- {
- return YES;
- }
-
- return NO;
- }
- XSClass XSRuntime_GetClassForClassID( XSClassID classID )
- {
- if( classID == 0 )
- {
- return NULL;
- }
-
- if( classID > __xsruntime_class_count )
- {
- return NULL;
- }
-
- return ( XSClass )&( __xsruntime_class_table[ classID - 1 ] );
- }
- XSClassID XSRuntime_GetClassIDForClass( XSClass cls )
- {
- XSUInteger i;
-
- if( cls == NULL )
- {
- return 0;
- }
-
- for( i = 0; i < __xsruntime_class_count; i++ )
- {
- if( &( __xsruntime_class_table[ i ] ) == cls )
- {
- return i + 1;
- }
- }
-
- return 0;
- }
- XSClassID XSRuntime_GetClassIDForClassWithName( const char * name )
- {
- XSUInteger i;
-
- if( name == NULL )
- {
- return 0;
- }
-
- for( i = 0; i < __xsruntime_class_count; i++ )
- {
- if( strcmp( __xsruntime_class_table[ i ].classInfos->className, name ) == 0 )
- {
- return i + 1;
- }
- }
-
- return 0;
- }
- XSClass XSRuntime_GetClassForObject( XSObject object )
- {
- if( object == NULL )
- {
- return NULL;
- }
-
- if( XSRuntime_IsInstance( object ) == NO )
- {
- return NULL;
- }
-
- return ( ( XSInstance )object )->__class;
- }
- XSClassID XSRuntime_GetTypeIDForObject( XSObject object )
- {
- if( object == NULL )
- {
- return 0;
- }
-
- if( XSRuntime_IsInstance( object ) == NO )
- {
- return 0;
- }
-
- return XSRuntime_GetClassIDForClass( XSRuntime_GetClassForObject( object ) );
- }
- const char * XSRuntime_GetClassNameForClassID( XSClassID classID )
- {
- if( classID == 0 || classID > __xsruntime_class_count )
- {
- return "N/A";
- }
-
- return __xsruntime_class_table[ classID - 1 ].classInfos->className;
- }
- const char * XSRuntime_GetClassNameForClass( XSClass cls )
- {
- if( cls == NULL )
- {
- return NULL;
- }
-
- return cls->classInfos->className;
- }
- const char * XSRuntime_GetClassNameForObject( XSObject object )
- {
- if( object == NULL )
- {
- return NULL;
- }
-
- if( XSRuntime_IsInstance( object ) == NO )
- {
- return NULL;
- }
-
- return ( ( XSInstance )object )->__class->classInfos->className;
- }
- BOOL XSRuntime_IsInstanceOfClass( XSObject object, XSClass cls )
- {
- if( object == NULL || cls == NULL )
- {
- return NO;
- }
-
- if( XSRuntime_IsInstance( object ) == NO )
- {
- return NO;
- }
-
- if( ( ( XSInstance )object )->__class == cls )
- {
- return YES;
- }
-
- return NO;
- }
- BOOL XSRuntime_IsInstanceOfClassName( XSObject object, const char * name )
- {
- if( object == NULL || name == NULL )
- {
- return NO;
- }
-
- if( XSRuntime_IsInstance( object ) == NO )
- {
- return NO;
- }
-
- if( strcmp( ( ( XSRuntimeClass * )object )->classInfos->className, name ) == 0 )
- {
- return YES;
- }
-
- return NO;
- }