Exemple #1
0
protected func Initialize()
{
  // Local 0 und 1 sind die Lininenfarben
  SetLocal(0,66); 
  SetLocal(1,66);  
  // Die ersten beiden Vertices auf aktuelle Position legen
  SetVertex(0,0,GetX()); SetVertex(0,1,GetY());
  SetVertex(1,0,GetX()); SetVertex(1,1,GetY());
}
Exemple #2
0
CEMSocket::CEMSocket(const CProxyData *ProxyData)
	: CEncryptedStreamSocket(wxSOCKET_NOWAIT, ProxyData)
{
	// If an interface has been specified,
	// then we need to bind to it.
	if (!thePrefs::GetAddress().IsEmpty()) {
		amuleIPV4Address host;
		
		// No need to warn here, in case of failure to
		// assign the hostname. That is already done
		// in amule.cpp when starting ...
		if (host.Hostname(thePrefs::GetAddress())) {
			SetLocal(host);
		}
	}

	byConnected = ES_NOTCONNECTED;
	m_uTimeOut = CONNECTION_TIMEOUT; // default timeout for ed2k sockets

	// Download (pseudo) rate control	
	downloadLimit = 0;
	downloadLimitEnable = false;
	pendingOnReceive = false;

	// Download partial header
	pendingHeaderSize = 0;

	// Download partial packet
	pendingPacket = NULL;
	pendingPacketSize = 0;

	// Upload control
	sendbuffer = NULL;
	sendblen = 0;
	sent = 0;

    m_currentPacket_is_controlpacket = false;
	m_currentPackageIsFromPartFile = false;

    m_numberOfSentBytesCompleteFile = 0;
    m_numberOfSentBytesPartFile = 0;
    m_numberOfSentBytesControlPacket = 0;

    lastCalledSend = ::GetTickCount();
    lastSent = ::GetTickCount()-1000;

	m_bAccelerateUpload = false;

    m_actualPayloadSize = 0;
    m_actualPayloadSizeSent = 0;

    m_bBusy = false;
    m_hasSent = false;

	lastFinishedStandard = 0;

	DoingDestroy = false;
	
}
TCPClientSocket::TCPClientSocket(IPAddress &cServAddr, int iServPort)
        : TCPSocket((cServAddr.GetAddressFamily() == AF_INET6))
{
    Connect(cServAddr, iServPort);

    SetLocal();
    SetConnected();
}
TCPServerSocket::TCPServerSocket(int iPortNo, int iBackLog, bool bUseIPv6)
        : TCPSocket(bUseIPv6)
{
    const int   iReUseAddrFlag = 1;

    SetSockOpt(SOL_SOCKET, SO_REUSEADDR, &iReUseAddrFlag, sizeof(iReUseAddrFlag));
    Bind(iPortNo);
    SetLocal();
    Listen(iBackLog);
}
TCPServerSocket::TCPServerSocket(IPAddress &cLocalAddr, int iPortNo, int iBackLog)
        : TCPSocket((cLocalAddr.GetAddressFamily() == AF_INET6))
{
    const int   iReUseAddrFlag = 1;

    SetSockOpt(SOL_SOCKET, SO_REUSEADDR, &iReUseAddrFlag, sizeof(iReUseAddrFlag));
    Bind(cLocalAddr, iPortNo);
    SetLocal();
    Listen(iBackLog);
}
Exemple #6
0
status_t
InterfaceAddress::SetTo(const ifaliasreq& request)
{
	status_t status = SetLocal((const sockaddr*)&request.ifra_addr);
	if (status == B_OK)
		status = SetDestination((const sockaddr*)&request.ifra_broadaddr);
	if (status == B_OK)
		status = SetMask((const sockaddr*)&request.ifra_mask);

	return status;
}
Exemple #7
0
void RarTime::SetDos(uint DosTime)
{
  RarLocalTime lt;
  lt.Second=(DosTime & 0x1f)*2;
  lt.Minute=(DosTime>>5) & 0x3f;
  lt.Hour=(DosTime>>11) & 0x1f;
  lt.Day=(DosTime>>16) & 0x1f;
  lt.Month=(DosTime>>21) & 0x0f;
  lt.Year=(DosTime>>25)+1980;
  lt.Reminder=0;
  SetLocal(&lt);
}
		bool Time::Set(wcstring const path)
		{
			NST_ASSERT( path && *path );

			WIN32_FILE_ATTRIBUTE_DATA data;
			SYSTEMTIME system, local;

			if
			(
				!::GetFileAttributesEx( path, GetFileExInfoStandard, &data ) ||
				!::FileTimeToSystemTime( &data.ftLastWriteTime, &system ) ||
				!::SystemTimeToTzSpecificLocalTime( NULL, &system, &local )
			)
				return false;

			SetLocal( &local );

			return true;
		}
	VariableHolder::VariableHolder(VariableHolder const& _other): data(SINEW(Data)), argument_namer(_other.argument_namer) {
		names_t	const &			names				= static_cast<Data*>(_other.data)->names;
		args_t	const &			args				= static_cast<Data*>(_other.data)->args;
		args_ordered_t const &	args_ordered		= static_cast<Data*>(_other.data)->args_ordered;
		nciter_t const			names_end			= names.end();
		aciter_t const			args_end			= args.end();
		oaciter_t const			args_ordered_end	= args_ordered.end();
		
		// copy variables
		for (nciter_t ite = names.begin(); ite != names_end; ++ite) {
			MemoryCell* assigned = 0x00;
			MemoryCell::Assign(assigned, ite->second);
			SetLocal(ite->first, assigned);
		}
		// copy args
		for (aciter_t ite = args.begin(); ite != args_end; ++ite) {
			MemoryCell* assigned = 0x00;
			MemoryCell::Assign(assigned, ite->second);
			AppendArgument(ite->first, assigned);
		}
	}
Exemple #10
0
void RarTime::SetIsoText(const wchar *TimeText)
{
  int Field[6];
  memset(Field,0,sizeof(Field));
  for (uint DigitCount=0;*TimeText!=0;TimeText++)
    if (IsDigit(*TimeText))
    {
      int FieldPos=DigitCount<4 ? 0:(DigitCount-4)/2+1;
      if (FieldPos<ASIZE(Field))
        Field[FieldPos]=Field[FieldPos]*10+*TimeText-'0';
      DigitCount++;
    }
  RarLocalTime lt;
  lt.Second=Field[5];
  lt.Minute=Field[4];
  lt.Hour=Field[3];
  lt.Day=Field[2]==0 ? 1:Field[2];
  lt.Month=Field[1]==0 ? 1:Field[1];
  lt.Year=Field[0];
  lt.Reminder=0;
  SetLocal(&lt);
}
void CCodComplexAtributeView::UpdateSelection()
{
	ASSERT_VALID(m_SplitterFrame);

	CQmonntDoc *pDoc = dynamic_cast<CQmonntDoc *>(GetDocument());
	ASSERT_VALID(pDoc);

	CNodeInfoSet *pSelection = m_SplitterFrame->GetTreeSelection();
	ASSERT(NULL != pSelection);
	pDoc->GetComplexAtributeSet(&m_LocalComplexAtributeSet, pSelection);

	DPRINTF(("***************** ComplexAtributeSet **********************"));
	m_LocalComplexAtributeSet.DebugOut();

	m_ComplexAtributePage.SetLocalComplexAtributeSet(&m_LocalComplexAtributeSet);

	CPropertyPage *ActivePage = m_PropertySheet.GetActivePage();
	ASSERT_VALID(ActivePage);
	ActivePage->OnInitDialog();

	SetModified(m_LocalComplexAtributeSet.IsModified());
	SetLocal(m_LocalComplexAtributeSet.IsLocal());
	SetAged(false);
}
		void Time::Set()
		{
			SYSTEMTIME local;
			::GetLocalTime( &local );
			SetLocal( &local );
		}
Exemple #13
0
void UUnb
( AbstractDistMatrix<F>& APre,
  AbstractDistMatrix<F>& householderScalarsPre )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<F,F,MC,MR> AProx( APre );
    DistMatrixWriteProxy<F,F,STAR,STAR>
      householderScalarsProx( householderScalarsPre );
    auto& A = AProx.Get();
    auto& householderScalars = householderScalarsProx.Get();

    const Grid& g = A.Grid();
    const Int n = A.Height();
    const Int householderScalarsHeight = Max(n-1,0);
    householderScalars.SetGrid( g );
    householderScalars.Resize( householderScalarsHeight, 1 );

    DistMatrix<F,MC,STAR> a21_MC(g);
    DistMatrix<F,MR,STAR> a21_MR(g);
    DistMatrix<F,MC,STAR> x1_MC(g); 
    DistMatrix<F,MR,STAR> x12Adj_MR(g);

    for( Int k=0; k<n-1; ++k )
    {
        const Range<Int> ind1( k,   k+1 ),
                         ind2( k+1, n   );

        auto a21 = A( ind2,    ind1 );
        auto A22 = A( ind2,    ind2 );
        auto A2  = A( IR(0,n), ind2 );

        auto alpha21T = A( IR(k+1,k+2), ind1 );
        auto a21B     = A( IR(k+2,n),   ind1 );

        // Find tau and v such that
        //  / I - tau | 1 | | 1, v^H | \ | alpha21T | = | beta |
        //  \         | v |            / |     a21B |   |    0 |
        const F tau = LeftReflector( alpha21T, a21B );
        householderScalars.Set(k,0,tau);

        // Temporarily set a21 := | 1 |
        //                        | v |
        F beta=0;
        if( alpha21T.IsLocal(0,0) )
            beta = alpha21T.GetLocal(0,0);
        alpha21T.Set(0,0,F(1));

        // A2 := A2 Hous(a21,tau)^H
        //     = A2 (I - conj(tau) a21 a21^H)
        //     = A2 - conj(tau) (A2 a21) a21^H
        // -----------------------------------
        // x1 := A2 a21
        a21_MR.AlignWith( A2 );
        a21_MR = a21;
        x1_MC.AlignWith( A2 );
        Zeros( x1_MC, n, 1 );
        LocalGemv( NORMAL, F(1), A2, a21_MR, F(0), x1_MC );
        El::AllReduce( x1_MC, A2.RowComm() );
        // A2 := A2 - conj(tau) x1 a21^H
        LocalGer( -Conj(tau), x1_MC, a21_MR, A2 ); 

        // A22 := Hous(a21,tau) A22
        //      = (I - tau a21 a21^H) A22
        //      = A22 - tau a21 (A22^H a21)^H
        // ----------------------------------
        // x12^H := (a21^H A22)^H = A22^H a21
        a21_MC.AlignWith( A22 );
        a21_MC = a21;
        x12Adj_MR.AlignWith( A22 );
        Zeros( x12Adj_MR, A22.Width(), 1 );
        LocalGemv( ADJOINT, F(1), A22, a21_MC, F(0), x12Adj_MR );
        El::AllReduce( x12Adj_MR, A22.ColComm() );
        // A22 := A22 - tau a21 x12
        LocalGer( -tau, a21_MC, x12Adj_MR, A22 );

        // Put beta back 
        if( alpha21T.IsLocal(0,0) )
            alpha21T.SetLocal(0,0,beta);
    }
}
TCPSocket::TCPSocket(int iNewSockDesc)
        : SocketBase(iNewSockDesc), bIsConnected(false)
{
    SetLocal();
}
Exemple #15
0
void ExecuteCycle(VM* vm)
{
	if(vm->pc == -1) return;
	if(vm->debug)
		printf("pc %i: ", vm->pc);
	
	if(vm->stackSize < vm->numGlobals)
		printf("Global(s) were removed from the stack!\n");
	
	switch(vm->program[vm->pc])
	{
		case OP_PUSH_NULL:
		{
			if(vm->debug)
				printf("push_null\n");
			++vm->pc;
			PushObject(vm, &NullObject);
		} break;
		
		case OP_PUSH_NUMBER:
		{
			if(vm->debug)
				printf("push_number\n");
			++vm->pc;
			int index = ReadInteger(vm);
			PushNumber(vm, vm->numberConstants[index]);
		} break;
		
		case OP_PUSH_STRING:
		{
			if(vm->debug)
				printf("push_string\n");
			++vm->pc;
			int index = ReadInteger(vm);
			PushString(vm, vm->stringConstants[index]);
		} break;
		
		case OP_PUSH_FUNC:
		{
			if(vm->debug)
				printf("push_func\n");
			Word hasEllipsis = vm->program[++vm->pc];
			Word isExtern = vm->program[++vm->pc];
			Word numArgs = vm->program[++vm->pc];
			++vm->pc;
			int index = ReadInteger(vm);
			
			PushFunc(vm, index, hasEllipsis, isExtern, numArgs);
		} break;
		
		case OP_PUSH_DICT:
		{
			if(vm->debug)
				printf("push_dict\n");
			++vm->pc;
			PushDict(vm);
		} break;

		case OP_CREATE_DICT_BLOCK:
		{
			if(vm->debug)
				printf("create_dict_block\n");
			++vm->pc;
			int length = ReadInteger(vm);
			Object* obj = PushDict(vm);
			if(length > 0)
			{
				// stack (before dict) is filled with key-value pairs (backwards, key is higher on stack)
				for(int i = 0; i < length * 2; i += 2)
					DictPut(&obj->dict, vm->stack[vm->stackSize - i - 2]->string.raw, vm->stack[vm->stackSize - i - 3]);
				vm->stackSize -= length * 2;
				vm->stack[vm->stackSize - 1] = obj;
			}
		} break;

		case OP_CREATE_ARRAY:
		{
			if(vm->debug)
				printf("create_array\n");
			++vm->pc;
			int length = (int)PopNumber(vm);
			PushArray(vm, length);
		} break;
		
		case OP_CREATE_ARRAY_BLOCK:
		{
			if(vm->debug)
				printf("create_array_block\n");
			++vm->pc;
			int length = ReadInteger(vm);
			Object* obj = PushArray(vm, length);
			if(length > 0)
			{
				for(int i = 0; i < length; ++i)
					obj->array.members[length - i - 1] = vm->stack[vm->stackSize - 2 - i];
				vm->stackSize -= length;
				vm->stack[vm->stackSize - 1] = obj;
			}
		} break;

		case OP_LENGTH:
		{
			if(vm->debug)
				printf("length\n");
			++vm->pc;
			Object* obj = PopObject(vm);
			if(obj->type == OBJ_STRING)
				PushNumber(vm, strlen(obj->string.raw));
			else if(obj->type == OBJ_ARRAY)
				PushNumber(vm, obj->array.length);
			else
			{
				fprintf(stderr, "Attempted to get length of %s\n", ObjectTypeNames[obj->type]);
				exit(1);
			}
		} break;
		
		case OP_ARRAY_PUSH:
		{
			if(vm->debug)
				printf("array_push\n");
			++vm->pc;
			
			Object* obj = PopArrayObject(vm);
			Object* value = PopObject(vm);

			while(obj->array.length + 1 >= obj->array.capacity)
			{
				obj->array.capacity *= 2;
				obj->array.members = erealloc(obj->array.members, obj->array.capacity * sizeof(Object*));
			}
			
			obj->array.members[obj->array.length++] = value;
		} break;
		
		case OP_ARRAY_POP:
		{
			if(vm->debug)
				printf("array_pop\n");
			++vm->pc;
			Object* obj = PopArrayObject(vm);
			if(obj->array.length <= 0)
			{
				fprintf(stderr, "Cannot pop from empty array\n");
				exit(1);
			}
			
			PushObject(vm, obj->array.members[--obj->array.length]);
		} break;
		
		case OP_ARRAY_CLEAR:
		{
			if(vm->debug)
				printf("array_clear\n");
			++vm->pc;
			Object* obj = PopArrayObject(vm);
			obj->array.length = 0;
		} break;

		case OP_DICT_SET:
		{
			if(vm->debug)
				printf("dict_set\n");
			++vm->pc;
			Object* obj = PopDict(vm);
			const char* key = PopString(vm);
			Object* value = PopObject(vm);
			
			DictPut(&obj->dict, key, value);
		} break;
		
		case OP_DICT_GET:
		{
			if(vm->debug)
				printf("dict_get\n");
			++vm->pc;
			Object* obj = PopDict(vm);
			const char* key = PopString(vm);
			
			Object* value = DictGet(&obj->dict, key);
			if(value)
				PushObject(vm, value);
			else
				PushObject(vm, &NullObject);
		} break;

		case OP_DICT_PAIRS:
		{
			if(vm->debug)
				printf("dict_pairs\n");
			++vm->pc;
			Object* obj = PopDict(vm);
			Object* aobj = PushArray(vm, obj->dict.numEntries);
			
			int len = 0;
			for(int i = 0; i <= obj->dict.capacity; ++i)
			{
				DictNode* node = obj->dict.buckets[i];
				while(node)
				{
					Object* pair = PushArray(vm, 2);
					
					Object* key = NewObject(vm, OBJ_STRING);
					key->string.raw = estrdup(node->key);
					
					pair->array.members[0] = key;
					pair->array.members[1] = node->value;
					
					aobj->array.members[len++] = PopObject(vm);
					
					node = node->next;
				}
			}
		} break;
		
		#define BIN_OP_TYPE(op, operator, type) case OP_##op: { if(vm->debug) printf("%s\n", #op); Object* val2 = PopObject(vm); Object* val1 = PopObject(vm); PushNumber(vm, (type)val1->number operator (type)val2->number); ++vm->pc; } break;
		#define BIN_OP(op, operator) BIN_OP_TYPE(op, operator, double)
		
		BIN_OP(ADD, +)
		BIN_OP(SUB, -)
		BIN_OP(MUL, *)
		BIN_OP(DIV, /)
		BIN_OP_TYPE(MOD, %, int)
		BIN_OP_TYPE(OR, |, int)
		BIN_OP_TYPE(AND, &, int)
		BIN_OP(LT, <)
		BIN_OP(LTE, <=)
		BIN_OP(GT, >)
		BIN_OP(GTE, >=)
		BIN_OP_TYPE(LOGICAL_AND, &&, int)
		BIN_OP_TYPE(LOGICAL_OR, ||, int)
		
		#define CBIN_OP(op, operator) case OP_##op: { ++vm->pc; if(vm->debug) printf("%s\n", #op); Object* b = PopObject(vm); Object* a = PopObject(vm); a->number operator b->number; } break;
		
		CBIN_OP(CADD, +=)
		CBIN_OP(CSUB, -=)
		CBIN_OP(CMUL, *=)
		CBIN_OP(CDIV, /=)
		
		case OP_EQU:
		{
			++vm->pc;
			Object* o2 = PopObject(vm);
			Object* o1 = PopObject(vm);
			
			if(o1->type != o2->type) PushNumber(vm, 0);
			else
			{
				if(o1->type == OBJ_STRING) { PushNumber(vm, strcmp(o1->string.raw, o2->string.raw) == 0); }
				else if(o1->type == OBJ_NUMBER) { PushNumber(vm, o1->number == o2->number); }
				else PushNumber(vm, o1 == o2);
			}
		} break;
		
		case OP_NEQU:
		{
			++vm->pc;
			Object* o2 = PopObject(vm);
			Object* o1 = PopObject(vm);
			
			if(o1->type != o2->type) PushNumber(vm, 1);
			else
			{
				if(o1->type == OBJ_STRING) { PushNumber(vm, strcmp(o1->string.raw, o2->string.raw) != 0); }
				else if(o1->type == OBJ_NUMBER) { PushNumber(vm, o1->number != o2->number); }
				else PushNumber(vm, o1 != o2);
			}
		} break;
		
		case OP_NEG:
		{
			if(vm->debug)
				printf("neg\n");
			
			++vm->pc;
			Object* obj = PopObject(vm);
			PushNumber(vm, -obj->number);
		} break;
		
		case OP_LOGICAL_NOT:
		{
			if(vm->debug)
				printf("not\n");
			
			++vm->pc;
			Object* obj = PopObject(vm);
			PushNumber(vm, !obj->number);
		} break;
		
		case OP_SETINDEX:
		{
			++vm->pc;

			Object* obj = PopObject(vm);
			Object* indexObj = PopObject(vm);
			Object* value = PopObject(vm);
			if(vm->debug)
				printf("setindex\n");
			
			if(obj->type == OBJ_ARRAY)
			{
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index array with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				int index = (int)indexObj->number;
				
				int arrayLength = obj->array.length;
				Object** members = obj->array.members;
				
				if(index >= 0 && index < arrayLength)
					members[index] = value;
				else
				{
					fprintf(stderr, "Invalid array index %i\n", index);
					exit(1);
				}
			}
			else if(obj->type == OBJ_STRING)
			{				
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index string with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				if(value->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to assign a %s to an index of a string '%s' (expected number/character)\n", ObjectTypeNames[value->type], obj->string.raw);
					exit(1);
				}
				
				obj->string.raw[(int)indexObj->number] = (char)value->number;
			}
			else if(obj->type == OBJ_DICT)
			{
				if(indexObj->type != OBJ_STRING)
				{
					fprintf(stderr, "Attempted to index dict with a %s (expected string)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				DictPut(&obj->dict, indexObj->string.raw, value);
			}
			else
			{
				fprintf(stderr, "Attempted to index a %s\n", ObjectTypeNames[obj->type]);
				exit(1);
			}
		} break;

		case OP_GETINDEX:
		{
			++vm->pc;

			Object* obj = PopObject(vm);
			Object* indexObj = PopObject(vm);

			if(obj->type == OBJ_ARRAY)
			{
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index array with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				int index = (int)indexObj->number;
				
				int arrayLength = obj->array.length;
				Object** members = obj->array.members;
				
				if(index >= 0 && index < arrayLength)
				{
					if(members[index])
						PushObject(vm, members[index]);
					else
					{
						fprintf(stderr, "attempted to index non-existent value in array\n");
						exit(1);
					}
					if(vm->debug)
						printf("getindex %i\n", index);
				}
				else
				{
					fprintf(stderr, "Invalid array index %i\n", index);
					exit(1);
				}
			}
			else if(obj->type == OBJ_STRING)
			{
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index string with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				PushNumber(vm, obj->string.raw[(int)indexObj->number]);
			}
			else if(obj->type == OBJ_DICT)
			{
				if(indexObj->type != OBJ_STRING)
				{
					fprintf(stderr, "Attempted to index dict with a %s (expected string)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				Object* val = (Object*)DictGet(&obj->dict, indexObj->string.raw);
				if(val)
					PushObject(vm, val);
				else
					PushObject(vm, &NullObject);
			}
			else 
			{
				fprintf(stderr, "Attempted to index a %s\n", ObjectTypeNames[obj->type]);
				exit(1);
			}
		} break;

		case OP_SET:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			
			Object* top = PopObject(vm);
			vm->stack[index] = top;
			
			if(vm->debug)
			{
				if(top->type == OBJ_NUMBER) printf("set %i to %g\n", index, top->number);
				else if(top->type == OBJ_STRING) printf("set %i to %s\n", index, top->string);	
			}
		} break;
		
		case OP_GET:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			if(vm->stack[index])
				PushObject(vm, (vm->stack[index]));
			else
				PushObject(vm, &NullObject);
				
			if(vm->debug)
				printf("get %i\n", index);
		} break;
		
		case OP_WRITE:
		{
			if(vm->debug)
				printf("write\n");
			Object* top = PopObject(vm);
			WriteObject(vm, top);
			printf("\n");
			++vm->pc;
		} break;
		
		case OP_READ:
		{
			if(vm->debug)
				printf("read\n");
			char* string = ReadStringFromStdin();
			PushString(vm, string);
			free(string);
			++vm->pc;
		} break;
		
		case OP_GOTO:
		{
			++vm->pc;
			int pc = ReadInteger(vm);
			vm->pc = pc;
		
			if(vm->debug)
				printf("goto %i\n", vm->pc);
		} break;
		
		case OP_GOTOZ:
		{
			++vm->pc;
			int pc = ReadInteger(vm);
			
			Object* top = PopObject(vm);
			if(top->number == 0)
			{
				vm->pc = pc;
				if(vm->debug)
					printf("gotoz %i\n", vm->pc);
			}
		} break;
		
		case OP_CALL:
		{
			Word nargs = vm->program[++vm->pc];
			++vm->pc;
			int index = ReadInteger(vm);

			if(vm->debug)
				printf("call %s\n", vm->functionNames[index]);

			PushIndir(vm, nargs);

			vm->pc = vm->functionPcs[index];
		} break;
		
		case OP_CALLP:
		{
			Word hasEllipsis, isExtern, numArgs;
			Word nargs = vm->program[++vm->pc];
			++vm->pc;
			int id = PopFunc(vm, &hasEllipsis, &isExtern, &numArgs);
			
			if(vm->debug)
				printf("callp %s%s\n", isExtern ? "extern " : "", isExtern ? vm->externNames[id] : vm->functionNames[id]);
			
			if(isExtern)
				vm->externs[id](vm);
			else
			{
				if(!hasEllipsis)
				{
					if(nargs != numArgs)
					{
						fprintf(stderr, "Function '%s' expected %i args but recieved %i args\n", vm->functionNames[id], numArgs, nargs);
						exit(1);
					}
				}
				else
				{
					if(nargs < numArgs)
					{
						fprintf(stderr, "Function '%s' expected at least %i args but recieved %i args\n", vm->functionNames[id], numArgs, nargs);
						exit(1);
					}
				}
				
				if(!hasEllipsis) PushIndir(vm, nargs);
				else
				{
					// runtime collapsing of arguments:
					// the concrete arguments (known during compilation) are on the top of
					// the stack. We create an array (by pushing it and then decrementing the
					// stack pointer) and fill it up with the ellipsed arguments (behind the
					// concrete arguments). We then place this array just before the concrete
					// arguments in the stack so that it can be accessed as an argument "args".
					// The indirection info is pushed onto the indirection stack (the concrete and
					// non-concrete [aside from the one that the 'args' array replaces] are still 
					// present on the stack, so all of the arguments are to be removed)
					
					/*printf("args:\n");
					for(int i = 0; i < nargs; ++i)
					{
						WriteObject(vm, vm->stack[vm->stackSize - i - 1]);
						printf("\n");
					}
					printf("end\n");*/
					
					//printf("members:\n");
					Object* obj = PushArray(vm, nargs - numArgs);
					vm->stackSize -= 1;
					for(int i = 0; i < obj->array.length; ++i)
					{
						obj->array.members[i] = vm->stack[vm->stackSize - numArgs - 1 - i];
						/*WriteObject(vm, obj->array.members[i]);
						printf("\n");*/
					}
					//printf("end\n");
					
					vm->stack[vm->stackSize - numArgs - 1] = obj;
					
					/*printf("final args:\n");
					for(int i = 0; i < numArgs + 1; ++i)
					{
						WriteObject(vm, vm->stack[vm->stackSize - i - 1]);
						printf("\n");
					}
					printf("end\n");*/
					
					PushIndir(vm, nargs);
				}
				
				vm->pc = vm->functionPcs[id];
			}
		} break;
		
		case OP_RETURN:
		{
			if(vm->debug)
				printf("ret\n");
			PopIndir(vm);
		} break;
		
		case OP_RETURN_VALUE:
		{
			if(vm->debug)
				printf("retval\n");
			Object* returnValue = PopObject(vm);
			PopIndir(vm);
			PushObject(vm, returnValue);
		} break;
		
		case OP_CALLF:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			if(vm->debug)
				printf("callf %s\n", vm->externNames[index]);
			vm->externs[index](vm);
		} break;

		case OP_GETLOCAL:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			PushObject(vm, GetLocal(vm, index));
			if(vm->debug)
				printf("getlocal %i (fp: %i, stack size: %i)\n", index, vm->fp, vm->stackSize);
		} break;
		
		case OP_SETLOCAL:
		{
			if(vm->debug)
				printf("setlocal\n");
			++vm->pc;
			int index = ReadInteger(vm);
			SetLocal(vm, index, PopObject(vm));
		} break;
		
		case OP_HALT:
		{
			if(vm->debug)
				printf("halt\n");
			vm->pc = -1;
		} break;
		
		default:
			printf("Invalid instruction %i\n", vm->program[vm->pc]);
			break;
	}
}