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; }
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; }
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; }
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 }
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; }
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; }