static int getgetStackPointer(void) { int n=4; // local variable to cause change to stack pointer n+=getStackPointer(); if (n==0) n=getStackPointer()+37; // this never happens - it's just to defeat the optimiser return (n-4); }
/* GCのマークフェーズ */ static void gc_mark(void) { int i; /* スタックトップと, スタックを指すポインタを取得 */ int stack_top = getStackTop(); LL1LL_Value *stack_p = getStackPointer(); LL1LL_Object *pos; /* 全マークをリセット */ for (pos = heap_head; pos != NULL; pos = pos->next) pos->marked = LL1LL_FALSE; /* スタック(参照できるオブジェクト)を走査 */ for (i = 0; i < stack_top; i++) { if (stack_p[i].type != LL1LL_OBJECT_TYPE) { /* オブジェクトでないなら次へ */ continue; } else { /* マークを付ける */ if (is_string(stack_p[i])) { stack_p[i].u.object->marked = LL1LL_TRUE; } else { /* should be ARRAY_OBJECT here */ array_mark(stack_p[i].u.object); /* 配列マークのルーチンへ */ } } } }
// Yield to another user thread. void yield(void) { labelhack(Resume); DEBUG_PRINT("Put self in readyQ and suspend\n"); Registers saveArea; void* localStubBase = stubBase; DEBUG_PRINT("stacklet %p cannot be freed\n", stubBase - STACKLET_SIZE); DEBUG_PRINT("Store stubBase in localStubBase %p\n", localStubBase); saveRegisters(); void* stackPointer; getStackPointer(stackPointer); enqReadyQ(&&Resume, stackPointer); suspendStub(); Resume: restoreRegisters(); stubBase = localStubBase; DEBUG_PRINT("stacklet %p can be freed\n", stubBase - STACKLET_SIZE); DEBUG_PRINT("Restore stubBase to be %p.\n", stubBase); DEBUG_PRINT("Resumed a ready thread.\n"); }
void setjmp_longjmp() { volatile int i,r,j,k,l,m; // volatile to rid us of warnings volatile int sp1,sp2; TheTest.Next(_L("Setjmp")); sp1=getStackPointer(); sp2=getgetStackPointer(); TEST(sp1!=sp2); // call from deeper function nesting should give a different answer memset(jbufs[0],0,sizeof(jmp_buf)); memset(jbufs[1],0,sizeof(jmp_buf)); memset(jbufs[2],0,sizeof(jmp_buf)); r=setjmp(jbufs[0]); TEST(r==0); for (i=0,j=1,k=2,l=3,m=4; i<3; i++,j*=3,k+=j,l*=m,m-=2) { r=setjmp(jbufs[i]); TEST(r==0); TEST(j>i); } r=memcmp(jbufs[0],jbufs[2], sizeof(jmp_buf)); if (r!=0) { RDebug::Print(_L(" Test code appears to be using preserved registers (a good thing)\n")); RDebug::Print(_L(" buf @ %08x %08x\n"), jbufs[0], jbufs[2]); for (i=0;i<16;i++) { if (jbufs[0][i] != jbufs[2][i]) RDebug::Print(_L(" buf+%02d: %08x %08x\n"), i*4, jbufs[0][i], jbufs[2][i]); } } else RDebug::Print(_L(" Test code appears not to exercise preserved registers\n")); r=setjmp(jbufs[0]); TEST(r==0); r=setjmp(jbufs[2]); TEST(r==0); r=memcmp(jbufs[0],jbufs[2], sizeof(jmp_buf)); TEST(r!=0); /* must change the return address! */ TheTest.Next(_L("Setjmp and longjmp")); r=setjmp(jbufs[0]); if (r==0) { TEST(count==0); count++; longjmp(jbufs[0],7); } else if (r==7) { TEST(count==1); count++; longjmp(jbufs[0],3); } else if (r==3) { TEST(count==2); count++; longjmp(jbufs[0],0); /* 0 must be turned into 1 */ } else { TEST(r==1); TEST(count==3); count++; } sp1=getStackPointer(); r=setjmp(jbufs[3]); if (r==0) { sp2=getStackPointer(); TEST(sp1==sp2); longjmp(jbufs[3],1); // simple setjmp/longjmp } else if (r==1) { sp2=getStackPointer(); TEST(sp1==sp2); jmp_nest(20); // more complex example } else { TEST(r==100); sp2=getStackPointer(); TEST(sp1==sp2); } }
/* setDynamicValue: set cell at index to value on stack */ void setDynamicValue( Array *array, Symbol *s ) { int index, hi, lo, isNew, c; char *key; Variant *stackData; ArrayCell *cell; /* make sure there is a value to set */ if (tos == 0) { ePrintf( Runtime, "setDynamicValue: stack underflow" ); } /* create the key */ key = buildKey( array, s ); /* assume it will be a new key */ isNew = 1; /* binary search */ lo = 0; hi = array->lower[0]-1; index = 0; while (lo <= hi) { index = floor((lo + hi) / 2); cell = array->data.cell+index; c = strcmp( key, cell->key ); if (c < 0) { hi = index - 1; } else if (c > 0) { lo = index + 1; } else { /* found prior key */ isNew = 0; break; } } /* no prior key? */ if (isNew) { /* create empty cell */ index = lo; insertDynamicCell( array, index ); } /* address of cell */ cell = array->data.cell + index; /* need to set key? */ if (isNew) { /* use key (already unique copy) */ cell->key = key; } else { /* don't need key */ eFree( key ); /* clean up old value */ if (cell->data.datatype == DATA_STRING) { eFree( cell->data.value.string ); } } /* resolve datatype */ stackData = getStackPointer( tos ); cell->data.datatype = stackData->datatype; if (stackData->datatype == DATA_STRING) { /* ref? */ if (stack[tos].datatype == DATA_REF) { /* need to make a unique copy */ cell->data.value.string = eCopyString( stackData->value.string ); } else { /* use directly */ cell->data.value.string = stackData->value.string; } } else if (stackData->datatype == DATA_NUMBER) { cell->data.value.number = stackData->value.number; } else { /* oops */ ePrintf( Runtime, "Can't assign %s to a Dynamic Array", datumName[stackData->datatype] ); } tos--; }
int rntGetStack(void) { return getStackPointer(); }