示例#1
0
int prIdentDict_PutGet(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, *b, *c, *d, *slot, *newslot;
	int i, index, size;
	PyrObject *dict;
	PyrObject *array;

	a = g->sp - 2;  // dict
	b = g->sp - 1;	// key
	c = g->sp;		// value
	d = ++g->sp;	// push the stack to save the receiver

	slotCopy(d,a);
	dict = slotRawObject(d);
	array = slotRawObject(&dict->slots[ivxIdentDict_array]);
	if (!isKindOf((PyrObject*)array, class_array)) {
		SetNil(a);
		--g->sp;
		return errFailed;
	}

	index = arrayAtIdentityHashInPairs(array, b);
	slot = array->slots + index;
	slotCopy(a,&slot[1]);
	slotCopy(&slot[1],c);
	g->gc->GCWrite(array, c);
	if (IsNil(slot)) {
		slotCopy(slot,b);
		g->gc->GCWrite(array, b);
		size = slotRawInt(&dict->slots[ivxIdentDict_size]) + 1;
		SetRaw(&dict->slots[ivxIdentDict_size], size);
		if (array->size < size*3) {
			PyrObject *newarray;
			newarray = newPyrArray(g->gc, size*3, 0, true);
			newarray->size = ARRAYMAXINDEXSIZE(newarray);
			nilSlots(newarray->slots, newarray->size);
			slot = array->slots;
			for (i=0; i<array->size; i+=2, slot+=2) {
				if (NotNil(slot)) {
					index = arrayAtIdentityHashInPairs(newarray, slot);
					newslot = newarray->slots + index;
					slotCopy(&newslot[0],&slot[0]);
					slotCopy(&newslot[1],&slot[1]);
				}
			}
			SetRaw(&dict->slots[ivxIdentDict_array], newarray);
			g->gc->GCWriteNew(dict, newarray); // we know newarray is white so we can use GCWriteNew
		}
	}
	--g->sp;
	return errNone;
}
示例#2
0
int identDictPut(struct VMGlobals *g, PyrObject *dict, PyrSlot *key, PyrSlot *value)
{
	PyrSlot *slot, *newslot;
	int i, index, size;
	PyrObject *array;

	bool knows = IsTrue(dict->slots + ivxIdentDict_know);
	if (knows && IsSym(key)) {
		if (slotRawSymbol(key) == s_parent) {
			slotCopy(&dict->slots[ivxIdentDict_parent],value);
			g->gc->GCWrite(dict, value);
			return errNone;
		}
		if (slotRawSymbol(key) == s_proto) {
			slotCopy(&dict->slots[ivxIdentDict_proto],value);
			g->gc->GCWrite(dict, value);
			return errNone;
		}
	}
	array = slotRawObject(&dict->slots[ivxIdentDict_array]);
	if (array->IsImmutable()) return errImmutableObject;
	if (!isKindOf((PyrObject*)array, class_array)) return errFailed;

	index = arrayAtIdentityHashInPairs(array, key);
	slot = array->slots + index;
	slotCopy(&slot[1],value);
	g->gc->GCWrite(array, value);
	if (IsNil(slot)) {
		slotCopy(slot,key);
		g->gc->GCWrite(array, key);
		size = slotRawInt(&dict->slots[ivxIdentDict_size]) + 1;
		SetRaw(&dict->slots[ivxIdentDict_size], size);
		if (array->size < size*3) {
			PyrObject *newarray;
			newarray = newPyrArray(g->gc, size*3, 0, false);
			newarray->size = ARRAYMAXINDEXSIZE(newarray);
			nilSlots(newarray->slots, newarray->size);
			slot = array->slots;
			for (i=0; i<array->size; i+=2, slot+=2) {
				if (NotNil(slot)) {
					index = arrayAtIdentityHashInPairs(newarray, slot);
					newslot = newarray->slots + index;
					slotCopy(&newslot[0],&slot[0]);
					slotCopy(&newslot[1],&slot[1]);
				}
			}
			SetRaw(&dict->slots[ivxIdentDict_array], newarray);
			g->gc->GCWriteNew(dict, newarray); // we know newarray is white so we can use GCWriteNew
		}
	}
	return errNone;
}
示例#3
0
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, key, dur, stretch, delta;
	double fdur, fstretch;
	int err;

	a = g->sp;  // dict

	SetSymbol(&key, s_delta);
	identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta);

	if (NotNil(&delta)) {
		slotCopy(a,&delta);
	} else {
		SetSymbol(&key, s_dur);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur);

		err = slotDoubleVal(&dur, &fdur);
		if (err) {
			if (NotNil(&dur)) return err;
			SetNil(a);
			return errNone;
		}

		SetSymbol(&key, s_stretch);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch);

		err = slotDoubleVal(&stretch, &fstretch);
		if (err) {
			if (NotNil(&stretch)) return err;
			SetFloat(a, fdur);
			return errNone;
		}

		SetFloat(a, fdur * fstretch );
	}

	return errNone;
}
示例#4
0
int identDictPut(struct VMGlobals *g, PyrObject *dict, PyrSlot *key, PyrSlot *value)
{
	PyrSlot *slot, *newslot;
	int i, index, size;
	PyrObject *array;

	bool knows = IsTrue(dict->slots + ivxIdentDict_know);
	if (knows && IsSym(key)) {
		if (key->us == s_parent) {
			slotCopy(&dict->slots[ivxIdentDict_parent],value);
			g->gc->GCWrite(dict, value);
			return errNone;
		}
		if (key->us == s_proto) {
			slotCopy(&dict->slots[ivxIdentDict_proto],value);
			g->gc->GCWrite(dict, value);
			return errNone;
		}
	}
	array = dict->slots[ivxIdentDict_array].uo;
	if (!isKindOf((PyrObject*)array, class_array)) return errFailed;

	index = arrayAtIdentityHashInPairs(array, key);
	slot = array->slots + index;
	slotCopy(&slot[1],value);
	g->gc->GCWrite(array, value);
	if (IsNil(slot)) {
		slotCopy(slot,key);
		g->gc->GCWrite(array, key);
		size = ++dict->slots[ivxIdentDict_size].ui;
		if (array->size < size*3) {
			PyrObject *newarray;
			newarray = newPyrArray(g->gc, size*3, 0, false);
			newarray->size = ARRAYMAXINDEXSIZE(newarray);
			nilSlots(newarray->slots, newarray->size);
			slot = array->slots;
			for (i=0; i<array->size; i+=2, slot+=2) {
				if (NotNil(slot)) {
					index = arrayAtIdentityHashInPairs(newarray, slot);
					newslot = newarray->slots + index;
					slotCopy(&newslot[0],&slot[0]);
					slotCopy(&newslot[1],&slot[1]);
				}
			}
			dict->slots[ivxIdentDict_array].uo = newarray;
			g->gc->GCWrite(dict, newarray);
		}
	}
	return errNone;
}
void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector,
	long numArgsPushed)
{
	PyrSlot *qslot, *pslot, *pend;
	long i, index;
	PyrSlot *uniqueMethodSlot, *arraySlot, *recvrSlot, *selSlot, *slot;
	PyrClass *classobj;
	PyrMethod *meth;
	PyrObject *array;

#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
	// move args up by one to make room for selector
	qslot = g->sp + 1;
	pslot = g->sp + 2;
	pend = pslot - numArgsPushed + 1;
	while (pslot > pend) *--pslot = *--qslot;

	selSlot = g->sp - numArgsPushed + 2;
	SetSymbol(selSlot, selector);
	g->sp++;

	recvrSlot = selSlot - 1;

	classobj = classOfSlot(recvrSlot);

	index = slotRawInt(&classobj->classIndex) + s_nocomprendo->u.index;
	meth = gRowTable[index];


	if (slotRawClass(&meth->ownerclass) == class_object) {
		// lookup instance specific method
		uniqueMethodSlot = &g->classvars->slots[cvxUniqueMethods];
		if (isKindOfSlot(uniqueMethodSlot, class_identdict)) {
			arraySlot = slotRawObject(uniqueMethodSlot)->slots + ivxIdentDict_array;
			if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) {
				i = arrayAtIdentityHashInPairs(array, recvrSlot);
				if (i >= 0) {
					slot = array->slots + i;
					if (NotNil(slot)) {
						++slot;
						if (isKindOfSlot(slot, class_identdict)) {
							arraySlot = slotRawObject(slot)->slots + ivxIdentDict_array;
							if ((IsObj(arraySlot) && (array = slotRawObject(arraySlot))->classptr == class_array)) {
								i = arrayAtIdentityHashInPairs(array, selSlot);
								if (i >= 0) {
									slot = array->slots + i;
									if (NotNil(slot)) {
										++slot;
										slotCopy(selSlot, recvrSlot);
										slotCopy(recvrSlot, slot);
										blockValue(g, (int)numArgsPushed+1);
										return;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	executeMethod(g, meth, numArgsPushed+1);

#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
}
HOT void returnFromMethod(VMGlobals *g)
{
	PyrFrame *returnFrame, *curframe, *homeContext;
	PyrMethod *meth;
	PyrMethodRaw *methraw;
	curframe = g->frame;

	//assert(slotRawFrame(&curframe->context) == NULL);

	/*if (gTraceInterpreter) {
		post("returnFromMethod %s:%s\n", slotRawClass(&g->method->ownerclass)->name.us->name, g->slotRawSymbol(&method->name)->name);
		post("tailcall %d\n", g->tailCall);
	}*/
#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
	homeContext = slotRawFrame(&slotRawFrame(&curframe->context)->homeContext);
	if (homeContext == NULL) {
		null_return:
#if TAILCALLOPTIMIZE
		if (g->tailCall) return; // do nothing.
#endif

	/*
		static bool once = true;
		if (once || gTraceInterpreter)
		{
			once = false;
			post("return all the way out. sd %d\n", g->sp - g->gc->Stack()->slots);
			postfl("%s:%s\n",
				slotRawClass(&g->method->ownerclass)->name.us->name, g->slotRawSymbol(&method->name)->name
			);
			post("tailcall %d\n", g->tailCall);
			post("homeContext %p\n", homeContext);
			post("returnFrame %p\n", returnFrame);
			dumpObjectSlot(&homeContext->caller);
			DumpStack(g, g->sp);
			DumpBackTrace(g);
		}
		gTraceInterpreter = false;
	*/
		//if (IsNil(&homeContext->caller)) return; // do nothing.

		// return all the way out.
		PyrSlot *bottom = g->gc->Stack()->slots;
		slotCopy(bottom, g->sp);
		g->sp = bottom; // ??!! pop everybody
		g->method = NULL;
		g->block = NULL;
		g->frame = NULL;
		longjmp(g->escapeInterpreter, 2);
	} else {
		returnFrame = slotRawFrame(&homeContext->caller);

		if (returnFrame == NULL) goto null_return;
		// make sure returnFrame is a caller and find earliest stack frame
		{
			PyrFrame *tempFrame = curframe;
			while (tempFrame != returnFrame) {
				tempFrame = slotRawFrame(&tempFrame->caller);
				if (!tempFrame) {
					if (isKindOf((PyrObject*)g->thread, class_routine) && NotNil(&g->thread->parent)) {
						// not found, so yield to parent thread and continue searching.
						PyrSlot value;
						slotCopy(&value, g->sp);

						int numArgsPushed = 1;
						switchToThread(g, slotRawThread(&g->thread->parent), tSuspended, &numArgsPushed);

						// on the other side of the looking glass, put the yielded value on the stack as the result..
						g->sp -= numArgsPushed - 1;
						slotCopy(g->sp, &value);

						curframe = tempFrame = g->frame;
					} else {
						slotCopy(&g->sp[2], &g->sp[0]);
						slotCopy(g->sp, &g->receiver);
						g->sp++; SetObject(g->sp, g->method);
						g->sp++;
						sendMessage(g, getsym("outOfContextReturn"), 3);
						return;
					}
				}
			}
		}

		{
			PyrFrame *tempFrame = curframe;
			while (tempFrame != returnFrame) {
				meth = slotRawMethod(&tempFrame->method);
				methraw = METHRAW(meth);
				PyrFrame *nextFrame = slotRawFrame(&tempFrame->caller);
				if (!methraw->needsHeapContext) {
					SetInt(&tempFrame->caller, 0);
				} else {
					if (tempFrame != homeContext)
						SetInt(&tempFrame->caller, 0);
				}
				tempFrame = nextFrame;
			}
		}

		// return to it
		g->ip = (unsigned char *)slotRawPtr(&returnFrame->ip);
		g->frame = returnFrame;
		g->block = slotRawBlock(&returnFrame->method);

		homeContext = slotRawFrame(&returnFrame->homeContext);
		meth = slotRawMethod(&homeContext->method);
		methraw = METHRAW(meth);

#if DEBUGMETHODS
if (gTraceInterpreter) {
	postfl("%s:%s <- %s:%s\n",
		slotRawSymbol(&slotRawClass(&meth->ownerclass)->name)->name, slotRawSymbol(&meth->name)->name,
		slotRawSymbol(&slotRawClass(&g->method->ownerclass)->name)->name, slotRawSymbol(&g->method->name)->name
	);
}
#endif

		g->method = meth;
		slotCopy(&g->receiver, &homeContext->vars[0]);

	}
#ifdef GC_SANITYCHECK
	g->gc->SanityCheck();
#endif
}
示例#7
0
int prBootInProcessServer(VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp;

	if (!gInternalSynthServer.mWorld) {
		SetPrintFunc(&vpost);
		WorldOptions options = kDefaultWorldOptions;

		PyrObject *optionsObj = a->uo;
		PyrSlot *optionsSlots = optionsObj->slots;

		static char mInputStreamsEnabled[512], mOutputStreamsEnabled[512], mDeviceName[512];
		int err;

		err = slotIntVal(optionsSlots + 0, (int*)&options.mNumAudioBusChannels);
		if (err) return err;

		err = slotIntVal(optionsSlots + 1, (int*)&options.mNumControlBusChannels);
		if (err) return err;

		err = slotIntVal(optionsSlots + 2, (int*)&options.mNumInputBusChannels);
		if (err) return err;

		err = slotIntVal(optionsSlots + 3, (int*)&options.mNumOutputBusChannels);
		if (err) return err;

		err = slotIntVal(optionsSlots + 4, (int*)&options.mNumBuffers);
		if (err) return err;

		err = slotIntVal(optionsSlots + 5, (int*)&options.mMaxNodes);
		if (err) return err;

		err = slotIntVal(optionsSlots + 6, (int*)&options.mMaxGraphDefs);
		if (err) return err;

		err = slotIntVal(optionsSlots + 8, (int*)&options.mBufLength);
		if (err) return err;

		if (NotNil(optionsSlots + 9)) {
			err = slotIntVal(optionsSlots + 9, (int*)&options.mPreferredHardwareBufferFrameSize);
			if (err) return err;
		}

		err = slotIntVal(optionsSlots + 10, (int*)&options.mRealTimeMemorySize);
		if (err) return err;

		err = slotIntVal(optionsSlots + 11, (int*)&options.mNumRGens);
		if (err) return err;

		err = slotIntVal(optionsSlots + 12, (int*)&options.mMaxWireBufs);
		if (err) return err;

		if (NotNil(optionsSlots + 13)) {
			err = slotIntVal(optionsSlots + 13, (int*)&options.mPreferredSampleRate);
			if (err) return err;
		}

		options.mLoadGraphDefs = IsTrue(optionsSlots + 14) ? 1 : 0;

		#ifdef SC_DARWIN
		err = slotStrVal(optionsSlots+15, mInputStreamsEnabled, 512);
		if(err) options.mInputStreamsEnabled = NULL;
		else options.mInputStreamsEnabled = mInputStreamsEnabled;

		err = slotStrVal(optionsSlots+16, mOutputStreamsEnabled, 512);
		if(err) options.mOutputStreamsEnabled = NULL;
		else options.mOutputStreamsEnabled = mOutputStreamsEnabled;
		#endif

		err = slotStrVal(optionsSlots+17, mDeviceName, 512);
		if(err) options.mInDeviceName = options.mOutDeviceName = NULL;
		else options.mInDeviceName = options.mOutDeviceName = mDeviceName;

		options.mNumSharedControls = gInternalSynthServer.mNumSharedControls;
		options.mSharedControls = gInternalSynthServer.mSharedControls;

		gInternalSynthServer.mWorld = World_New(&options);
	}

	return errNone;
}
示例#8
0
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a, key, dur, stretch, delta;
	double fdur, fstretch;
	int err;
	PyrClass *restClass = getsym("Rest")->u.classobj;
	PyrSlot *slot;

	a = g->sp;  // dict

	SetSymbol(&key, s_delta);
	identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta);

	if (NotNil(&delta)) {
		if (isKindOfSlot(&delta, restClass)) {
			slot = slotRawObject(&delta)->slots;
			err = slotDoubleVal(slot, &fdur);
		} else {
			err = slotDoubleVal(&delta, &fdur);
		}
		if (err) {
			return err;
		} else {
			SetFloat(a, fdur);
			return errNone;
		}
	} else {
		SetSymbol(&key, s_dur);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur);
		err = slotDoubleVal(&dur, &fdur);
		if (err) {
			if (IsNil(&dur)) {
				SetNil(g->sp);
				return errNone;
			} else if (isKindOfSlot(&dur, restClass)) {
				slot = slotRawObject(&dur)->slots;
				err = slotDoubleVal(slot, &fdur);
				if (err)
					return err;
			} else {
				return errWrongType;
			}
		}
		SetSymbol(&key, s_stretch);
		identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch);

		err = slotDoubleVal(&stretch, &fstretch);
		if (err) {
			if (NotNil(&stretch)) {
				if (isKindOfSlot(&stretch, restClass)) {
					slot = slotRawObject(&stretch)->slots;
					err = slotDoubleVal(slot, &fstretch);
					if (err) return err;
				} else {
					return errWrongType;
				}
			} else {
				SetFloat(a, fdur);
				return errNone;
			}
		}

		SetFloat(a, fdur * fstretch);
	}

	return errNone;
}