This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

A crash with libffi


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,
I'm trying to write a FFI module for another language using libffi (I'm using 
gcc 3.3.5).
In short, it's crashing. The code is big and bloated with implementations 
details of that particular language, so, I'll try you to show you here what I 
am doing (the whole file would be attached anyway). Note: calling functions 
without parameters already works, I'm trying to get parameters to work.

First, I define some variables:
unsigned int argCount;
void *funcHandle;
ffi_type **argTypes;
void **argValues;
ffi_type *returnType;
void *returnValue;
ffi_cif cif;

I fill the variables:
funcHandle = byteArrayToPointer(funcHandleBA);
argCount = PSObject_arraySize((struct Object*) argValuesOA);
argTypes = malloc(sizeof(*argTypes) * argCount);
argValues = malloc(sizeof(*argValues) * argCount);

and then I try to fill argTypes and argValues accordingly, this is the new 
code (the rest is tested and working):
{
unsigned char *temp = malloc(sizeof(*temp));
if(temp == 0){
 fprintf(stderr, "Couldn't allocate memory for unsigned char *t.\n");
 return CurrentMemory->NilObject;
}
argTypes[argIndex] = &ffi_type_uchar;
*temp = 52; // Arbitrary number to test FFI, latter on it'd be a call that 
gets the real parameter value, like the previous PSObject_arraySize((struct 
Object*) argValuesOA);
argValues[argIndex] = temp;
break;
}

Do you see anything wrong there ?

Latter on I get the return type:
returnType = &ffi_type_uchar; break;

I prepare the function:
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argCount, returnType, argTypes)

make space for the return value (this part, for example, is known to work):
returnValue = malloc(sizeof(unsigned char));

And I call the function:
ffi_call(&cif, funcHandle, returnValue, argValues);

There where it crashes. I've compiled libffi with debug symbols and this is 
the backtrace I'm getting:
#0  0x00000000 in ?? ()
#1  0xb7fa557f in ffi_call_SYSV () 
from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.5-20050130/libffi-2.00-beta.so
#2  0xb7fa5245 in ffi_call () 
from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.5-20050130/libffi-2.00-beta.so
#3  0x0804bdb5 in ffiCallFunction (funcHandleBA=0xb7142ba4, 
argValuesOA=0xb71e71b0, argTypesOA=0xb71510d8, resultTypeOP=3) at 
slateffi.c:320
#4  0x0805590e in _primitive103 (interpreter=0xb6f1b6c8, arguments=0xb70a332c, 
argumentsSize=5, optionals=0x0) at vm.c:4967
#5  0x0805134e in PSInterpreter_send_to_through_arity_withOptionals_ 
(i=0xb6f1b6c8, selector=3069307404, args=0xb70a332c, dispatchers=0xb70a332c, 
n=5, opts=0x0) at vm.c:3167
#6  0x0805658a in PSInterpreter_sendMessage_withOptionals_ (i=0xb6f1b6c8, n=5, 
opts=0x0) at vm.c:1054
#7  0x08052357 in PSInterpreter_interpret (i=0xb6f1b6c8) at vm.c:3523
#8  0x08049757 in slateMain (argc=2, argv=0xbffff074) at boot.c:164
#9  0x0804caf2 in main (argc=2, argv=0xbffff074) at main.c:5

Do you know what might be the first function ?

Well, any help is appretiated, as I mentioned before, the whole is attached, 
but it contains a lot of irrelevant implementation details.
- -- 
Pupeno: pupeno@pupeno.com - http://pupeno.com
Reading Science Fiction ? http://sfreaders.com.ar
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFCav6efW48a9PWGkURAqxuAKCSfrDUTXklvpRV8m/tmylXMZDJPgCfQiUW
5ZgGXWDOYa9iEVebY37gQbY=
=42SN
-----END PGP SIGNATURE-----
/* Copyright 2004 Josà Pablo Ezequiel "Pupeno" FernÃndez <pupeno@pupeno.com>
   Based on work: Copyright (c) 2002 Lee Salzman, Brian T. Rice.
   Based on work done by: Ken Causey.

   This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. */

#include <stdio.h>
#include <dlfcn.h>
#include <ffi.h>

#include "slatevm.h"
#include "slateffi.h"

Bool ffiOpenLibrary(struct ByteArray *libNameBA, struct ByteArray *libHandleBA) {
	char *libName;
	void *libHandle;

	// Get the name of the library as a char*.
	libName = byteArrayToString(libNameBA);
	if(!libName) {
		fprintf(stderr, "Failed to convert the library's name from Slate's ByteArray to C's char*.\n");
		return False;
	}

	// Clear any existing error messages
	dlerror(); 

	// Open the library.
	// TODO: Do some effort in finding the library when a simple name is given (find /usr/X11R6/lib/libX11.so when only libX11 is given).
	libHandle = dlopen(libName, RTLD_LAZY);

	// Check if we succeeded in opening the library.
	if(libHandle == NULL) {
		// Now, we didn't.
		fprintf(stderr, "Failed to open library '%s':\n\t %s.\n", libName, dlerror());
		free(libName);
		return False;
	} else {
		// We opened, let's clean up.
		free(libName);
		// Turn the library pointer into a Slate object.
		pointerToByteArray(libHandle, libHandleBA);
		return True;
	}
}  

Bool ffiCloseLibrary(struct ByteArray *libHandleBA) {
	void *libHandle;

	//Initializate the libHandle pointer to what is contained in libHandleBA.
	libHandle = byteArrayToPointer(libHandleBA);

	// Close the library.
	return (dlclose(libHandle) == 0) ? True : False;
}

Bool ffiGetFunction(struct ByteArray *funcNameBA, struct ByteArray *funcHandleBA, struct ByteArray *libHandleBA) {
	void *funcHandle;
	void *libHandle;
	char *funcName;

	// Get a char* from the ByteArray of the function name.
	funcName = byteArrayToString(funcNameBA);
	if(funcName == NULL){
		fprintf(stderr, "Failed to convert the function's name from Slate's ByteArray to C's char*.\n");
		return False;
	}

	// Clear any existing error messages
	dlerror(); 

	// Initializate the libHandle pointer to what is contained in libHandleBA.
	libHandle = byteArrayToPointer(libHandleBA);

	// Get the handle for the function.
	funcHandle = dlsym(libHandle, funcName);

	// Check if we found the function.
	if(funcHandle == NULL) {
		// We didn't :(
		fprintf(stderr, "Failed to find function '%s':\n\t %s.\n", funcName, dlerror());
		free(funcName);
		return False;
	} else {
		// We did, let's clean up.
		free(funcName);
		// Turn the handle into a Slate object.
		pointerToByteArray(funcHandle, funcNameBA);
		// I believe the following line is not really needed.
		//memcpy(funcHandleBA->elements, &funcHandle, sizeof(funcHandle));
		return True;
	}
}

ObjectPointer ffiCallFunction(struct ByteArray *funcHandleBA,
                              struct OopArray *argValuesOA,
                              struct OopArray *argTypesOA,
                              ObjectPointer resultTypeOP){
	unsigned int argCount; // Hold how many arguments we are dealing with.
	void *funcHandle; // The handle of the function.
	ffi_type **argTypes; // The array of types of the arguments.
	void **argValues; // The array of the values of the arguments.
	ffi_type *returnType; // The return type.
	void *returnValue; // The return value.
	ffi_cif cif; // The cif structure, what libffi uses to make the calls.

	// Turn the ByteArray handler into real handler.
	funcHandle = byteArrayToPointer(funcHandleBA);
	
	// Put the count of arguments into argCount.
	argCount = PSObject_arraySize((struct Object*) argValuesOA);
	printf("Calling a function with %d arguments.\n", argCount);
	
	// Check if we have the same amount of types and values for arguments.
	if(argCount != PSObject_arraySize((struct Object*) argTypesOA)) {
		fprintf(stderr, "A different amount of arguments and types where received.\n");
		return CurrentMemory->NilObject;
	}
	printf("We have the same ammount of arguments and types, good!\n");
	
	// Save space for the arguments types and values in the arrays to be send to libffi.
	argTypes = malloc(sizeof(*argTypes) * argCount);
	if(argTypes == 0){
		fprintf(stderr, "Couldn't allocate memory for argTypes.\n");
		return CurrentMemory->NilObject;
	}
	argValues = malloc(sizeof(*argValues) * argCount);
	if(argValues == 0){
		fprintf(stderr, "Couldn't allocate memory for argValues.\n");
		return CurrentMemory->NilObject;
	}

	printf("Space was reserved for the argument types and values.\n");

	// Build the array of argument types and argument values.
	for(unsigned int argIndex = 0; argIndex < argCount; ++argIndex){
		// Grab the ObjectPointer for the argument we are processing now.
		ObjectPointer argumentOP = argValuesOA->elements[argIndex];

		printf("Figuring out type (and value, latter) of argument number: %d.\n", argIndex);

		switch(argTypesOA->elements[argIndex]){
			case FFI_FORMAT_UCHAR:{
				unsigned char *temp = malloc(sizeof(*temp));
				if(temp == 0){
					fprintf(stderr, "Couldn't allocate memory for unsigned char *t.\n");
					return CurrentMemory->NilObject;
				}
				argTypes[argIndex] = &ffi_type_uchar;
				*temp = 52;
				argValues[argIndex] = temp;
				break;
			}
			case FFI_FORMAT_SCHAR:{
				signed char *temp = malloc(sizeof(*temp));
				if(temp == 0){
					fprintf(stderr, "Couldn't allocate memory for unsigned char *t.\n");
					return CurrentMemory->NilObject;
				}
				argTypes[argIndex] = &ffi_type_schar;
				*temp = 57;
				argValues[argIndex] = t;
				break;
			}
			case FFI_FORMAT_USHORT:{
				unsigned short *temp = malloc(sizeof(*t));
				if(temp == 0){
					fprintf(stderr, "Couldn't allocate memory for unsigned short *t.\n");
					return CurrentMemory->NilObject;
				}
				argTypes[argIndex] = &ffi_type_ushort;
				*temp = 58;
				argValues[argIndex] = t;
				break;
			}
			case FFI_FORMAT_SSHORT:
				argTypes[argIndex] = &ffi_type_sshort; break;
			case FFI_FORMAT_UINT:
				argTypes[argIndex] = &ffi_type_uint; break;
			case FFI_FORMAT_SINT:
				argTypes[argIndex] = &ffi_type_sint; break;
			case FFI_FORMAT_ULONG:
				argTypes[argIndex] = &ffi_type_ulong; break;
			case FFI_FORMAT_SLONG:
				argTypes[argIndex] = &ffi_type_slong; break;
			case FFI_FORMAT_FLOAT:
				argTypes[argIndex] = &ffi_type_float; break;
			case FFI_FORMAT_DOUBLE:
				argTypes[argIndex] = &ffi_type_double; break;
			case FFI_FORMAT_LONGDOUBLE:
				argTypes[argIndex] = &ffi_type_longdouble; break;
			case FFI_FORMAT_POINTER:
				argTypes[argIndex] = &ffi_type_pointer; break;
			case FFI_FORMAT_UINT8:
				argTypes[argIndex] = &ffi_type_uint8; break;
			case FFI_FORMAT_SINT8:
				argTypes[argIndex] = &ffi_type_sint8; break;
			case FFI_FORMAT_UINT16:
				argTypes[argIndex] = &ffi_type_uint16; break;
			case FFI_FORMAT_SINT16:
				argTypes[argIndex] = &ffi_type_sint16; break;
			case FFI_FORMAT_UINT32:
				argTypes[argIndex] = &ffi_type_uint32; break;
			case FFI_FORMAT_SINT32:
				argTypes[argIndex] = &ffi_type_sint32; break;
			case FFI_FORMAT_UINT64:
				argTypes[argIndex] = &ffi_type_uint64; break;
			case FFI_FORMAT_SINT64:
				argTypes[argIndex] = &ffi_type_sint64; break;
				fprintf(stderr, "The type of argument %d is not valid.\n", argIndex);
				return CurrentMemory->NilObject;
		}
	}

	printf("Figuring out the return type.\n");
	// Return type.
	switch(resultTypeOP){
		case FFI_FORMAT_VOID:
			returnType = &ffi_type_void; break;
		case FFI_FORMAT_UCHAR:
			printf("The return type is: Unsigned Char.\n");
			returnType = &ffi_type_uchar; break;
		case FFI_FORMAT_SCHAR:
			returnType = &ffi_type_schar; break;
		case FFI_FORMAT_USHORT:
			returnType = &ffi_type_ushort; break;
		case FFI_FORMAT_SSHORT:
			returnType = &ffi_type_sshort; break;
		case FFI_FORMAT_UINT:
			returnType = &ffi_type_uint; break;
		case FFI_FORMAT_SINT:
			returnType = &ffi_type_sint; break;
		case FFI_FORMAT_ULONG:
			returnType = &ffi_type_ulong; break;
		case FFI_FORMAT_SLONG:
			returnType = &ffi_type_slong; break;
		case FFI_FORMAT_FLOAT:
			returnType = &ffi_type_float; break;
		case FFI_FORMAT_DOUBLE:
			returnType = &ffi_type_double; break;
		case FFI_FORMAT_LONGDOUBLE:
			returnType = &ffi_type_longdouble; break;
		case FFI_FORMAT_POINTER:
			returnType = &ffi_type_pointer; break;
		case FFI_FORMAT_UINT8:
			returnType = &ffi_type_uint8; break;
		case FFI_FORMAT_SINT8:
			returnType = &ffi_type_sint8; break;
		case FFI_FORMAT_UINT16:
			returnType = &ffi_type_uint16; break;
		case FFI_FORMAT_SINT16:
			returnType = &ffi_type_sint16; break;
		case FFI_FORMAT_UINT32:
			returnType = &ffi_type_uint32; break;
		case FFI_FORMAT_SINT32:
			returnType = &ffi_type_sint32; break;
		case FFI_FORMAT_UINT64:
			returnType = &ffi_type_uint64; break;
		case FFI_FORMAT_SINT64:
			returnType = &ffi_type_sint64; break;
		default:
			fprintf(stderr, "The return type is not valid.\n");
			return CurrentMemory->NilObject;
	}

	// Prepare the function to be called.
	if(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argCount, returnType, argTypes) != FFI_OK){
		// Failed to prepare the function.
		fprintf(stderr, "Couldn't initialize the function (the cif structure).\n");
		return CurrentMemory->NilObject;
	}
	printf("Function (cif structure) has been initialized.\n");

	printf("Allocating space for the return value.\n");
	// Make some space for the return value.
	switch(resultTypeOP){
		case FFI_FORMAT_UCHAR: returnValue = malloc(sizeof(unsigned char));break;
		case FFI_FORMAT_SCHAR: returnValue = malloc(sizeof(signed char));break;
		case FFI_FORMAT_USHORT: returnValue = malloc(sizeof(unsigned short));break;
		case FFI_FORMAT_SSHORT: returnValue = malloc(sizeof(signed short));break;
		case FFI_FORMAT_UINT: returnValue = malloc(sizeof(unsigned int));break;
		case FFI_FORMAT_SINT: returnValue = malloc(sizeof(signed int));break;
		case FFI_FORMAT_ULONG: returnValue = malloc(sizeof(unsigned long));break;
		case FFI_FORMAT_SLONG: returnValue = malloc(sizeof(signed long));break;
		case FFI_FORMAT_FLOAT: returnValue = malloc(sizeof(float));break;
		case FFI_FORMAT_DOUBLE: returnValue = malloc(sizeof(double));break;
		case FFI_FORMAT_LONGDOUBLE: returnValue = malloc(sizeof(long double));break;
		case FFI_FORMAT_POINTER: returnValue = malloc(sizeof(void*)); break;
		case FFI_FORMAT_UINT8: returnValue = malloc(sizeof(uint8_t));break;
		case FFI_FORMAT_SINT8: returnValue = malloc(sizeof(int8_t));break;
		case FFI_FORMAT_UINT16: returnValue = malloc(sizeof(uint16_t));break;
		case FFI_FORMAT_SINT16: returnValue = malloc(sizeof(int16_t));break;
		case FFI_FORMAT_UINT32: returnValue = malloc(sizeof(uint32_t));break;
		case FFI_FORMAT_SINT32: returnValue = malloc(sizeof(int32_t));break;
		case FFI_FORMAT_UINT64: returnValue = malloc(sizeof(uint64_t));break;
		case FFI_FORMAT_SINT64: returnValue = malloc(sizeof(int64_t));break;
	}

	printf("Space allocated.\nCalling the function.\n");
	
	// Call the function.
	ffi_call(&cif, funcHandle, returnValue, argValues);

	printf("Function called.\nExtracting the return value.\n");

	// Turn the return value into a Slate object and return it.
	switch(resultTypeOP){
		case FFI_FORMAT_VOID:
			return CurrentMemory -> NilObject;
		case FFI_FORMAT_UCHAR:
			return unsignedCharToObjectPointer(*(unsigned char*)returnValue);
		case FFI_FORMAT_SCHAR:
			return signedCharToObjectPointer(*(signed char*)returnValue);
		case FFI_FORMAT_USHORT:
			return unsignedShortToObjectPointer(*(unsigned short*)returnValue);
		case FFI_FORMAT_SSHORT:
			return signedShortToObjectPointer(*(signed short*)returnValue);
		case FFI_FORMAT_UINT:
			return unsignedIntToObjectPointer(*(unsigned int*)returnValue);
		case FFI_FORMAT_SINT:
			return signedIntToObjectPointer(*(signed int*)returnValue);
		case FFI_FORMAT_ULONG:
			return unsignedLongToObjectPointer(*(unsigned long*)returnValue);
		case FFI_FORMAT_SLONG:
			return signedLongToObjectPointer(*(signed long*)returnValue);
		case FFI_FORMAT_FLOAT:
			return floatToObjectPointer(*(float*)returnValue);
		case FFI_FORMAT_DOUBLE:
			fprintf(stderr, "Double is not yet supported by Slate, it seems.\n");
			return CurrentMemory -> NilObject;
			//return doubleToObjectPointer(*(double*)returnValue);
		case FFI_FORMAT_LONGDOUBLE:
			fprintf(stderr, "Long double is not yet supported by Slate, it seems.\n");
			return CurrentMemory -> NilObject;
			//return longDoubleToObjectPointer(*(long double*)returnValue);
		case FFI_FORMAT_POINTER:
			// We take the pointer as unsinged int for printing it.
			printf("The pointer return: %x", *(unsigned int*)returnValue);
			return pointerToObjectPointer(*(void**)returnValue);
		case FFI_FORMAT_UINT8:
			return unsignedInt8ToObjectPointer(*(uint8_t*)returnValue);
		case FFI_FORMAT_SINT8:
			return signedInt8ToObjectPointer(*(int8_t*)returnValue);
		case FFI_FORMAT_UINT16:
			return unsignedInt16ToObjectPointer(*(uint16_t*)returnValue);
		case FFI_FORMAT_SINT16:
			return signedInt16ToObjectPointer(*(int16_t*)returnValue);
		case FFI_FORMAT_UINT32:
			return unsignedInt32ToObjectPointer(*(uint32_t*)returnValue);
		case FFI_FORMAT_SINT32:
			return signedInt32ToObjectPointer(*(int32_t*)returnValue);
		case FFI_FORMAT_UINT64:
			return unsignedInt64ToObjectPointer(*(uint64_t*)returnValue);
		case FFI_FORMAT_SINT64:
			return signedInt64ToObjectPointer(*(int64_t*)returnValue);
	}
}


// Functions that might be located in a separated module for reusing in other extensions to Slate
char *byteArrayToString(struct ByteArray *stringBA) {
	size_t length = SIZE_OF_OBJECT((struct Object *) stringBA);

	// Reserve enough memroy for this string and the null character.
	char *charP = malloc(length + 1);
	if(charP == NULL){
		return NULL;
	}

	// Copy the elements in the stringBA to the string.
	memcpy(charP, stringBA->elements, length);
	// And the trailing null character.
	charP[length]='\0';

	return charP;
}

void *byteArrayToPointer(struct ByteArray *pointerBA){
	void *pointer;

	// Ensure that we have enough data in the pointerBA to copy to the pointer.
	assert(SIZE_OF_OBJECT(pointerBA) >= sizeof(pointer));

	// Make the copy.
	memcpy(&pointer, pointerBA->elements, sizeof(pointer));

	return pointer;
}

void pointerToByteArray(void *pointer, struct ByteArray *pointerBA){
	// Ensure that we have enough space in the ByteArray to hold to the pointer.
	assert(SIZE_OF_OBJECT(pointerBA) >= sizeof(pointer));

	// Make the copy.
	memcpy(pointerBA->elements, &pointer, sizeof(pointer));
}

unsigned char objectPointerToUChar(ObjectPointer op){
	unsigned char result;
	if(ObjectPointer_isSmallInt(op)){
		result = (unsigned char) ObjectPointer_asSmallInt(op);
	} else {
		result = *(unsigned char*)PSObject_arrayElements(ObjectPointer_pointer(op));
	}
	fprintf(stderr, "\t\tTurning an object into unsigned char %", result);
	return result;
}

ObjectPointer unsignedCharToObjectPointer(unsigned char from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

signed char objectPointerToSChar(ObjectPointer op){
	unsigned char result;
	if(ObjectPointer_isSmallInt(op)){
		result = (signed char) ObjectPointer_asSmallInt(op);
	} else {
		result = *(signed char*)PSObject_arrayElements(ObjectPointer_pointer(op));
	}
	fprintf(stderr, "\t\tTurning an object into unsigned char %d", result);
	return result;
}

ObjectPointer signedCharToObjectPointer(signed char from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer unsignedShortToObjectPointer(unsigned short from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedShortToObjectPointer(signed short from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer unsignedIntToObjectPointer(unsigned int from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedIntToObjectPointer(signed int from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer unsignedLongToObjectPointer(unsigned long from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedLongToObjectPointer(signed long from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer floatToObjectPointer(float from){
	return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_ (CurrentMemory, FloatProto, (Byte *) &from, sizeof(from)));
}

ObjectPointer doubleToObjectPointer(double from){
	return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_ (CurrentMemory, FloatProto, (Byte *) &from, sizeof(from)));
}

ObjectPointer longDoubleToObjectPointer(long double from){
	return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, FloatProto, (Byte *) &from, sizeof(from)));
}

ObjectPointer pointerToObjectPointer(void *from){
	return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte*)&from, sizeof(from)));
}

ObjectPointer unsignedInt8ToObjectPointer(uint8_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedInt8ToObjectPointer(int8_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer unsignedInt16ToObjectPointer(uint16_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedInt16ToObjectPointer(int16_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer unsignedInt32ToObjectPointer(uint32_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedInt32ToObjectPointer(int32_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer unsignedInt64ToObjectPointer(uint64_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

ObjectPointer signedInt64ToObjectPointer(int64_t from){
	if(signedLongInt_fitsSmallInt(from)){
		return unsignedLongInt_asObject(from);
	} else {
		return PSObject_asObject((struct Object *) PSObjectHeap_newByteArray_from_sized_(CurrentMemory, ByteArrayProto, (Byte *) &from, sizeof(from)));
	}
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]