Esempio n. 1
0
Oop* __fastcall Interpreter::primitiveNewFromStack(Oop* const stackPointer, unsigned)
{
	BehaviorOTE* oteClass = reinterpret_cast<BehaviorOTE*>(*(stackPointer - 1));

	Oop oopArg = (*stackPointer);
	SMALLINTEGER count;
	if (isIntegerObject(oopArg) && (count = ObjectMemoryIntegerValueOf(oopArg)) >= 0)
	{
		// Note that instantiateClassWithPointers counts up the class,
		PointersOTE* oteObj = ObjectMemory::newUninitializedPointerObject(oteClass, count);
		VariantObject* obj = oteObj->m_location;

		Oop* sp = stackPointer;
		sp = sp - count - 1;
		while (--count >= 0)
		{
			oopArg = *(sp + count);
			ObjectMemory::countUp(oopArg);
			obj->m_fields[count] = oopArg;
		}

		// Save down SP in case ZCT is reconciled on adding result
		m_registers.m_stackPointer = sp;
		*sp = reinterpret_cast<Oop>(oteObj);
		ObjectMemory::AddToZct((OTE*)oteObj);
		return sp;
	}
	else
	{
		return primitiveFailure(0);
	}
}
Esempio n. 2
0
primitiveAtPut(void)
{
    float *floatPtr;
    double floatValue;
    sqInt index;
    sqInt rcvr;
    sqInt value;

	value = stackValue(0);
	if (isIntegerObject(value)) {
		floatValue = ((double) (integerValueOf(value)) );
	}
	else {
		floatValue = floatValueOf(value);
	}
	index = stackIntegerValue(1);
	rcvr = stackValue(2);
	if (!((!(failed()))
		 && ((isWords(rcvr))
		 && ((index > 0)
		 && (index <= (slotSizeOf(rcvr))))))) {
		return primitiveFail();
	}
	floatPtr = firstIndexableField(rcvr);
	floatPtr[index - 1] = (((float) floatValue));
	popthenPush(3, value);
	return 0;
}
static sqInt
stackLightArrayValue(sqInt stackIndex)
{
	// B3DAcceleratorPlugin>>#stackLightArrayValue:
    sqInt array;
    sqInt arraySize;
    sqInt i;
    sqInt oop;

	array = stackObjectValue(stackIndex);
	if (array == null) {
return null;
	}
	if (array == (nilObject())) {
		return null;
	}
	if (!((fetchClassOf(array)) == (classArray()))) {
		return primitiveFail();
	}
	arraySize = slotSizeOf(array);
	for (i = 0; i <= (arraySize - 1); i += 1) {
		oop = fetchPointerofObject(i, array);
		if (isIntegerObject(oop)) {
			return primitiveFail();
		}
		if (!((isWords(oop))
			 && ((slotSizeOf(oop)) == 32))) {
			return primitiveFail();
		}
	}
	return array;
}
primitiveAtPut(void)
{
	// FloatArrayPlugin>>#primitiveAtPut
    float *floatPtr;
    double  floatValue;
    sqInt index;
    sqInt rcvr;
    sqInt value;

	value = stackValue(0);
	if (isIntegerObject(value)) {
		floatValue = ((double) (integerValueOf(value)) );
	}
	else {
floatValue = floatValueOf(value);
	}
	index = stackIntegerValue(1);
	rcvr = stackObjectValue(2);
	if (failed()) {
		return null;
	}
	success(isWords(rcvr));
	success((index > 0)
	 && (index <= (slotSizeOf(rcvr))));
	if (failed()) {
		return null;
	}
	floatPtr = firstIndexableField(rcvr);
	floatPtr[index - 1] = (((float) floatValue));
	if (!(failed())) {
		popthenPush(3, value);
	}
}
Esempio n. 5
0
Oop* __fastcall Interpreter::primitiveNewPinned(Oop* const sp, unsigned)
{
	BehaviorOTE* oteClass = reinterpret_cast<BehaviorOTE*>(*(sp - 1));
	Oop oopArg = (*sp);
	SMALLINTEGER size;
	if (isIntegerObject(oopArg) && (size = ObjectMemoryIntegerValueOf(oopArg)) >= 0)
	{
		InstanceSpecification instSpec = oteClass->m_location->m_instanceSpec;
		if (!(instSpec.m_pointers || instSpec.m_nonInstantiable))
		{
			BytesOTE* newObj = ObjectMemory::newByteObject<true, true>(oteClass, size);
			*(sp - 1) = reinterpret_cast<Oop>(newObj);
			ObjectMemory::AddToZct(reinterpret_cast<OTE*>(newObj));
			return sp - 1;
		}
		else
		{
			// Not indexable, or non-instantiable
			return primitiveFailure(instSpec.m_nonInstantiable ? 1 : 2);
		}
	}
	else
	{
		return primitiveFailure(0);	// Size must be positive SmallInteger
	}
}
primitiveFileTruncate(void)
{
	// FilePlugin>>#primitiveFileTruncate
    SQFile *file;
    sqInt objectPointer;
    sqInt sz;
    squeakFileOffsetType truncatePosition;

	if (!(isIntegerObject(stackValue(0)))) {
		sz = sizeof(squeakFileOffsetType);
		if ((byteSizeOf(stackValue(0))) > sz) {
			return primitiveFail();
		}
	}
	truncatePosition = positive64BitValueOf(stackValue(0));
	/* begin fileValueOf: */
	objectPointer = stackValue(1);
	if (!((isBytes(objectPointer))
		 && ((byteSizeOf(objectPointer)) == (sizeof(SQFile))))) {
		primitiveFail();
		file = null;
		goto l1;
	}
	file = firstIndexableField(objectPointer);
l1:	/* end fileValueOf: */;
	if (!(failed())) {
		sqFileTruncate(file, truncatePosition);
	}
	if (!(failed())) {
		pop(2);
	}
}
Esempio n. 7
0
OTE* __fastcall ObjectMemory::recursiveFree(OTE* rootOTE)
{
	HARDASSERT(!isIntegerObject(rootOTE));
	HARDASSERT(!isPermanent(rootOTE));
	HARDASSERT(!rootOTE->isFree());
	HARDASSERT(rootOTE->m_flags.m_count == 0);

#ifndef _AFX
	if (rootOTE->isFinalizable())
	{
		finalize(rootOTE);
		rootOTE->beUnfinalizable();
	}
	else
#endif
	{
		// Deal with the class first, as this is now held in the OTE
		recursiveCountDown(reinterpret_cast<POTE>(rootOTE->m_oteClass));

		if (rootOTE->isPointers())
		{
			// Recurse through referenced objects as necessary
			const MWORD lastPointer = rootOTE->getWordSize();
			Oop* pFields = reinterpret_cast<Oop*>(rootOTE->m_location);
			// Start after the header (only includes size now, which is not an Oop)
			for (MWORD i = ObjectHeaderSize; i < lastPointer; i++)
			{
				Oop fieldPointer = pFields[i];
				if (!isIntegerObject(fieldPointer))
				{
					OTE* fieldOTE = reinterpret_cast<OTE*>(fieldPointer);
					recursiveCountDown(fieldOTE);
				}
			}
		}

		deallocate(rootOTE);
	}

	return rootOTE;		// Important for some assembler routines - will be non-zero, so can act as TRUE
}
static AsyncFile *
asyncFileValueOf(sqInt oop)
{
	// AsynchFilePlugin>>#asyncFileValueOf:
	success((!(isIntegerObject(oop)))
	 && ((isBytes(oop))
	 && ((slotSizeOf(oop)) == (sizeof(AsyncFile)))));
	if (failed()) {
		return null;
	}
	return (AsyncFile *) (oop + 4);
}
Esempio n. 9
0
STDMETHODIMP_(VOID) CDolphinSmalltalk::MakeImmutable( 
		/* [in] */ Oop oop,
        /* [in] */ BOOL bImmutable)
{
	if (isIntegerObject(oop))
		return;

	if (bImmutable)
		reinterpret_cast<OTE*>(oop)->beImmutable();
	else
		reinterpret_cast<OTE*>(oop)->beMutable();
}
Esempio n. 10
0
Oop* __fastcall Interpreter::primitiveShallowCopy(Oop* const sp, unsigned)
{
	OTE* receiver = reinterpret_cast<OTE*>(*sp);
	ASSERT(!isIntegerObject(receiver));

	OTE* copy = receiver->m_flags.m_pointer
		? (OTE*)ObjectMemory::shallowCopy(reinterpret_cast<PointersOTE*>(receiver))
		: (OTE*)ObjectMemory::shallowCopy(reinterpret_cast<BytesOTE*>(receiver));
	*sp = (Oop)copy;
	ObjectMemory::AddToZct(copy);
	return sp;
}
Esempio n. 11
0
	/* Matrix2x3Plugin>>#loadArgumentPoint: */
static sqInt
loadArgumentPoint(sqInt point)
{
    int isInt;
    sqInt oop;

	if (failed()) {
		return null;
	}
	if (!((fetchClassOf(point)) == (classPoint()))) {
		return primitiveFail();
	}
	oop = fetchPointerofObject(0, point);
	isInt = isIntegerObject(oop);
	if (!(isInt
		 || (isFloatObject(oop)))) {
		return primitiveFail();
	}
	if (isInt) {
		m23ArgX = integerValueOf(oop);
	}
	else {
		m23ArgX = floatValueOf(oop);
	}
	oop = fetchPointerofObject(1, point);
	isInt = isIntegerObject(oop);
	if (!(isInt
		 || (isFloatObject(oop)))) {
		return primitiveFail();
	}
	if (isInt) {
		m23ArgY = integerValueOf(oop);
	}
	else {
		m23ArgY = floatValueOf(oop);
	}
	return 0;
}
Esempio n. 12
0
Oop* __fastcall Interpreter::primitiveNewWithArg(Oop* const sp, unsigned)
{
	BehaviorOTE* oteClass = reinterpret_cast<BehaviorOTE*>(*(sp - 1));
	Oop oopArg = (*sp);
	// Unfortunately the compiler can't be persuaded to perform this using just the sar and conditional jumps on no-carry and signed;
	// it generates both the bit test and the shift.
	SMALLINTEGER size;
	if (isIntegerObject(oopArg) && (size = ObjectMemoryIntegerValueOf(oopArg)) >= 0)
	{
		InstanceSpecification instSpec = oteClass->m_location->m_instanceSpec;
		if ((instSpec.m_value & (InstanceSpecification::IndexableMask | InstanceSpecification::NonInstantiableMask)) == InstanceSpecification::IndexableMask)
		{
			if (instSpec.m_pointers)
			{
				PointersOTE* newObj = ObjectMemory::newPointerObject(oteClass, size + instSpec.m_fixedFields);
				*(sp - 1) = reinterpret_cast<Oop>(newObj);
				ObjectMemory::AddToZct(reinterpret_cast<OTE*>(newObj));
				return sp - 1;
			}
			else
			{
				BytesOTE* newObj = ObjectMemory::newByteObject<true, true>(oteClass, size);
				*(sp - 1) = reinterpret_cast<Oop>(newObj);
				ObjectMemory::AddToZct(reinterpret_cast<OTE*>(newObj));
				return sp - 1;
			}
		}
		else
		{
			// Not indexable, or non-instantiable
			return primitiveFailure(instSpec.m_nonInstantiable ? 1 : 2);
		}
	}
	else
	{
		return primitiveFailure(0);	// Size must be positive SmallInteger
	}
}
Esempio n. 13
0
// Compact an object by updating all the Oops it contains using the
// forwarding pointers in the old OT.
void ObjectMemory::compactObject(OTE* ote)
{
	// We shouldn't come in here unless OTE already fixed for this object
	HARDASSERT(ote >= m_pOT && ote < m_pFreePointerList);

	// First fix up the class (remember that the new object pointer is stored in the
	// old one's object location slot
	compactOop(ote->m_oteClass);

	if (ote->isPointers())
	{
		VariantObject* varObj = static_cast<VariantObject*>(ote->m_location);
		const MWORD lastPointer = ote->pointersSize();
		for (MWORD i = 0; i < lastPointer; i++)
		{
			// This will get nicely optimised by the Compiler
			Oop fieldPointer = varObj->m_fields[i];

			// We don't need to visit SmallIntegers and objects we've already visited
			if (!isIntegerObject(fieldPointer))
			{
				OTE* fieldOTE = reinterpret_cast<OTE*>(fieldPointer);
				// If pointing at a free'd object ,then it has been moved
				if (fieldOTE->isFree())
				{
					// Should be one of the old OT entries, pointing outside the o
					Oop movedTo = reinterpret_cast<Oop>(fieldOTE->m_location);
					HARDASSERT(movedTo >= (Oop)m_pOT && movedTo < (Oop)m_pFreePointerList);
					// Get the new OTE from the old ...
					varObj->m_fields[i] = movedTo;
				}
			}
		}
	}
	// else, we don't even need to look at the body of byte objects any more
}
Esempio n. 14
0
static sqInt isNonIntegerObject(sqInt objectPointer)
{
	return !isIntegerObject(objectPointer);
}
Esempio n. 15
0
STDMETHODIMP_(BOOL) CDolphinSmalltalk::IsImmutable( 
		/* [in] */ Oop oop)
{
	return isIntegerObject(oop) || (reinterpret_cast<OTE*>(oop)->isImmutable());
}
Esempio n. 16
0
void ObjectMemory::FixupObject(OTE* ote, MWORD* oldLocation, const ImageHeader* pHeader)
{
	// Convert the class now separately
	BehaviorOTE* classPointer = reinterpret_cast<BehaviorOTE*>(FixupPointer(reinterpret_cast<OTE*>(ote->m_oteClass), static_cast<OTE*>(pHeader->BasePointer)));
#ifdef _DEBUG
	{
		PointersOTE* oteObj = reinterpret_cast<PointersOTE*>(ote);
		if (ote->isPointers() && (oteObj->getSize() % 2 == 1 ||
			classPointer == _Pointers.ClassByteArray ||
			classPointer == _Pointers.ClassAnsiString ||
			classPointer == _Pointers.ClassUtf8String ||
			classPointer == _Pointers.ClassSymbol))
		{
			TRACESTREAM<< L"Bad OTE for byte array " << LPVOID(&ote)<< L" marked as pointer" << std::endl;
			ote->beBytes();
		}
	}
#endif

	ote->m_oteClass = classPointer;

	if (ote->isPointers())
	{
		PointersOTE* otePointers = reinterpret_cast<PointersOTE*>(ote);
		VariantObject* obj = otePointers->m_location;

		const SMALLUNSIGNED numFields = ote->pointersSize();
		ASSERT(SMALLINTEGER(numFields) >= 0);
		// Fixup all the Oops
		for (SMALLUNSIGNED i = 0; i < numFields; i++)
		{
			Oop instPointer = obj->m_fields[i];
			if (!isIntegerObject(instPointer))
				obj->m_fields[i] = Oop(FixupPointer(reinterpret_cast<OTE*>(instPointer), static_cast<OTE*>(pHeader->BasePointer)));
		}

		if (classPointer == _Pointers.ClassProcess)
		{
			Process* process = static_cast<Process*>(ote->m_location);
			// We use the callbackDepth slot to store the delta in location
			// which we later use to adjust all the stack references.
			// The previous value is lost, but this is not important
			// as it must be reestablished as zero anyway
			process->BasicSetCallbackDepth(Oop(process) - Oop(oldLocation) + 1);
		}
		// else
		// MethodContext objects contain a pointer to their frame in the
		// stack, but we must fix that up later when walking down the stack.
	}
	else
	{
		if (classPointer == _Pointers.ClassExternalHandle)
		{
			// In Dolphin 4.0, all ExternalHandles are automatically nulled
			// on image load.

			ExternalHandle* handle = static_cast<ExternalHandle*>(ote->m_location);
			handle->m_handle = NULL;
		}
		// Look for the special image stamp object
		else if (classPointer == _Pointers.ClassContext)
		{
			ASSERT(ote->heapSpace() == OTEFlags::PoolSpace || ote->heapSpace() == OTEFlags::NormalSpace);

			// Can't deallocate now - must leave for collection later - maybe could go in the Zct though.
			VERIFY(ote->decRefs());
			deallocate(reinterpret_cast<OTE*>(ote));
		}
	}
}
Esempio n. 17
0
POBJECT ObjectMemory::basicResize(POTE ote, MWORD byteSize, int extra)
{
	ASSERT(!isIntegerObject(ote));
	POBJECT pObject;

/*	#ifdef _DEBUG
		TRACESTREAM << "Resizing ";
		Interpreter::printObject(Oop(ote), TRACESTREAM);
		TRACESTREAM << " (" << ote->m_location << ") from size " << ObjectMemory::sizeOf(ote) << " to size " << byteSize << "\n";
	#endif
*/
	switch(ote->heapSpace())
	{
		case OTEFlags::NormalSpace:
		{
//			TRACE("Resizing normal object...\n");
			pObject = ote->m_location;
			pObject = reallocChunk(pObject, byteSize+extra);

			if (pObject)
			{
				ote->m_location = pObject;
				ote->setSize(byteSize);
			}
			break;
		}

		case OTEFlags::VirtualSpace:
//			TRACE("Resizing virtual object...\n");
			pObject = resizeVirtual(ote, byteSize+extra);
			break;
	
		case OTEFlags::PoolSpace:
		{
			#if defined(_DEBUG)
				if (abs(Interpreter::executionTrace) > 0)
					checkPools();
			#endif

			// May be able to do some quicker resizing here if size is still in same pool?
			if ((byteSize+extra) > MaxSmallObjectSize)
			{
				pObject = allocChunk(byteSize+extra);
				ote->m_flags.m_space = OTEFlags::NormalSpace;
			}
			else
				pObject = allocSmallChunk(byteSize+extra);
	
			POBJECT pOldObject = ote->m_location;
			MWORD oldSize = ote->getSize();
			memcpy(pObject, pOldObject, min(oldSize, byteSize));
			freeSmallChunk(pOldObject, ote->sizeOf());
			ote->m_location = pObject;
			ote->setSize(byteSize);
			break;
		}

		default:
			// Not resizeable
			return NULL;
	}

	#if defined(_DEBUG)
		if (abs(Interpreter::executionTrace) > 0)
			checkPools();
//		TRACESTREAM << "After Resize: ";
//		Interpreter::printObject(Oop(ote), TRACESTREAM);
//		TRACESTREAM << "\n";
	#endif

	return pObject;
}
Esempio n. 18
0
void Process::PostLoadFix(ProcessOTE* oteThis)
{
	// Any overlapped call running when the image was saved is no longer valid, so
	// we must clear down the "pointer" and remove the back reference
	if (m_thread != reinterpret_cast<Oop>(Pointers.Nil))
	{
		m_thread = reinterpret_cast<Oop>(Pointers.Nil);
		oteThis->countDown();
	}

	// Patch any badly created or corrupted processes
	if (!ObjectMemoryIsIntegerObject(m_fpControl))
	{
		m_fpControl = ObjectMemoryIntegerObjectOf(_DN_SAVE | _RC_NEAR | _PC_64 | _EM_INEXACT | _EM_UNDERFLOW | _EM_OVERFLOW | _EM_DENORMAL);
	}

	Oop* pFramePointer = &m_suspendedFrame;
	Oop framePointer = *pFramePointer;
	const void* stackBase = m_stack;
	const void* stackEnd = reinterpret_cast<BYTE*>(this) + oteThis->getSize() - 1;

	// Wind down the stack adjusting references to self as we go
	// Start with the suspended context
	const int delta = m_callbackDepth - 1;
	while (isIntegerObject(framePointer) && framePointer != ZeroPointer)
	{
		framePointer += delta;
		if (framePointer < Oop(stackBase) || framePointer > Oop(stackEnd))
		{
			trace(L"Warning: Process at %#x has corrupt frame pointer at %#x which will be nilled\n", this, pFramePointer);
			*pFramePointer = Oop(Pointers.Nil);
			break;
		}
		else
			*pFramePointer += delta;

		StackFrame* pFrame = StackFrame::FromFrameOop(*pFramePointer);
		if (isIntegerObject(pFrame->m_bp))
		{
			pFrame->m_bp += delta;
		}

		ASSERT(reinterpret_cast<void*>(pFrame->m_bp) > stackBase && reinterpret_cast<void*>(pFrame->m_bp) < stackEnd);

		// If a stack only frame, then adjust the BP
		if (!isIntegerObject(pFrame->m_environment))
		{
			// The frame has an object context, we need to adjust
			// its back pointer to the frame if it is a MethodContext
			// The context objects contain no other addresses any more
			OTE* oteContext = reinterpret_cast<OTE*>(pFrame->m_environment);
			if (ObjectMemory::isAContext(oteContext))
			{
				Context* ctx = static_cast<Context*>(oteContext->m_location);
				if (isIntegerObject(ctx->m_frame) && ctx->m_frame != ZeroPointer)
				{
					ctx->m_frame += delta;
					ASSERT(reinterpret_cast<void*>(ctx->m_frame) > stackBase && reinterpret_cast<void*>(ctx->m_frame) < stackEnd);
				}
			}
		}

		// Adjust the contexts SP
		if (isIntegerObject(pFrame->m_sp))
		{
			pFrame->m_sp += delta;
			ASSERT(reinterpret_cast<void*>(pFrame->m_sp) >= stackBase && reinterpret_cast<void*>(pFrame->m_sp) <= stackEnd);
		}

		pFramePointer = &pFrame->m_caller;
		framePointer = *pFramePointer;
	}

	framePointer = SuspendedFrame();
	if (isIntegerObject(framePointer) && framePointer != ZeroPointer)
	{
		// The size of the process should exactly correspond with that required to
		// hold up to the SP of the suspended frame
		StackFrame* pFrame = StackFrame::FromFrameOop(framePointer);
		int size = (pFrame->m_sp - 1) - reinterpret_cast<DWORD>(this) + sizeof(Oop);
		if (size > 0 && unsigned(size) < oteThis->getSize())
		{
			TRACE(L"WARNING: Resizing process %p from %u to %u\n", oteThis, oteThis->getSize(), size);
			oteThis->setSize(size);
		}
	}
	// else its dead or not started yet

	// Later we'll use this slot to count the callback depth
	m_callbackDepth = ZeroPointer;
}