HRESULT CLR_RT_HeapBlock_Array::CreateInstance( CLR_RT_HeapBlock& reference, CLR_UINT32 length, const CLR_RT_ReflectionDef_Index& reflex )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* pArray;
    CLR_RT_TypeDef_Index    cls;
    CLR_RT_TypeDef_Instance inst;

    reference.SetObjectReference( NULL );

    if((CLR_INT32)length < 0) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    if(reflex.m_kind != REFLECTION_TYPE)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
    }

    if(reflex.m_levels == 1)
    {
        cls = reflex.m_data.m_type;
    }
    else
    {
        cls = g_CLR_RT_WellKnownTypes.m_Array;
    }

    if(inst.InitializeFromIndex( cls ) == false)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
    }
    else
    {
        CLR_DataType                 dt  = (CLR_DataType)inst.m_target->dataType;
        const CLR_RT_DataTypeLookup& dtl = c_CLR_RT_DataTypeLookup[ dt ];

        if(dtl.m_sizeInBytes == CLR_RT_DataTypeLookup::c_NA)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
        }

        pArray    = (CLR_RT_HeapBlock_Array*)g_CLR_RT_ExecutionEngine.ExtractHeapBlocksForArray( inst, length, reflex ); CHECK_ALLOCATION(pArray);

        reference.SetObjectReference( pArray );

        TINYCLR_SET_AND_LEAVE(pArray->ClearElements( 0, length ));
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::MarshalSockAddress( CLR_RT_HeapBlock& blkDst, const struct SOCK_sockaddr* addrSrc, CLR_UINT32 addrLenSrc )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* arr = NULL;

    CLR_RT_HeapBlock blkArr; blkArr.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC gc( blkArr );
    SOCK_sockaddr_in* dst;
    SOCK_sockaddr_in* src = (SOCK_sockaddr_in*)addrSrc;
        
    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( blkArr, addrLenSrc, g_CLR_RT_WellKnownTypes.m_UInt8 ));
    
    arr = blkArr.DereferenceArray();

    _ASSERTE(arr);

    dst = (SOCK_sockaddr_in*)arr->GetFirstElement();

    dst->sin_family           = SwapEndianIfBEc16(src->sin_family);
    dst->sin_port             = src->sin_port;
    dst->sin_addr.S_un.S_addr = src->sin_addr.S_un.S_addr;

    memcpy(dst->sin_zero, src->sin_zero, sizeof(dst->sin_zero));

    _ASSERTE(blkDst.DataType() == DATATYPE_BYREF || blkDst.DataType() == DATATYPE_ARRAY_BYREF);

    TINYCLR_CHECK_HRESULT(blkArr.StoreToReference( blkDst, 0 ));

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_String::CreateInstance( CLR_RT_HeapBlock& reference, LPCSTR szText, CLR_RT_Assembly* assm )
{        
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_String* str;

    reference.SetObjectReference( NULL );

    str = (CLR_RT_HeapBlock_String*)g_CLR_RT_ExecutionEngine.ExtractHeapBytesForObjects( DATATYPE_STRING, 0, sizeof(CLR_RT_HeapBlock_String) ); CHECK_ALLOCATION(str);

    reference.SetObjectReference( str );

#if defined(TINYCLR_NO_ASSEMBLY_STRINGS)            
    TINYCLR_CHECK_HRESULT( CLR_RT_HeapBlock_String::CreateInstance( reference, assm->GetString( CLR_DataFromTk( token ) ) ));    
#else
    str->SetStringText( szText, assm );
#endif

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_BinaryBlob::CreateInstance( CLR_RT_HeapBlock& reference, CLR_UINT32 length, CLR_RT_MarkingHandler mark, CLR_RT_RelocationHandler relocate, CLR_UINT32 flags )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_BinaryBlob* obj = Allocate( length, flags ); CHECK_ALLOCATION(obj);

    reference.SetObjectReference( obj );

    obj->SetBinaryBlobHandlers( mark, relocate );
    obj->m_assembly = NULL;

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_XmlNameTable::Grow()
{
    TINYCLR_HEADER();
    
    CLR_RT_HeapBlock_Array*              oldEntries;
    CLR_RT_HeapBlock                     newEntriesHB;
    CLR_RT_HeapBlock_Array*              newEntries;
    CLR_RT_HeapBlock_XmlNameTable_Entry* entry;
    CLR_RT_HeapBlock_XmlNameTable_Entry* next;
    CLR_RT_HeapBlock*                    newEntryHB;

    CLR_UINT32                           i;
    CLR_INT32                            newIndex;
    CLR_INT32                            newMask;

    newMask = GetMask() * 2 + 1;

    // allocate a new instance of Entry array
    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( newEntriesHB, newMask + 1, g_CLR_RT_WellKnownTypes.m_XmlNameTable_Entry ));

    newEntries = newEntriesHB.DereferenceArray();
    oldEntries = GetEntries();

    // Go through the old buckets, and resort them
    for(i = 0; i < oldEntries->m_numOfElements; i++)
    {
        entry = (CLR_RT_HeapBlock_XmlNameTable_Entry*)((CLR_RT_HeapBlock*)oldEntries->GetElement( i ))->Dereference();
    
        while(entry != NULL)
        {
            newIndex = entry->GetHashCode() & newMask;
            next = entry->GetNext();
    
            newEntryHB = (CLR_RT_HeapBlock*)newEntries->GetElement( newIndex );
    
            entry->SetNext( (CLR_RT_HeapBlock_XmlNameTable_Entry*)newEntryHB->Dereference() );
    
            newEntryHB->SetObjectReference( entry );
    
            entry = next;
        }
    }

    SetEntries( newEntries );
    SetMask   ( newMask    );

    TINYCLR_NOCLEANUP();
}
// May Trigger GC, but parameter value will be protected
HRESULT CLR_RT_HeapBlock_Queue::Enqueue( CLR_RT_HeapBlock* value )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* array    = GetArray();
    CLR_INT32               size     = GetSize();
    CLR_INT32               tail     = GetTail();
    CLR_INT32               capacity = array->m_numOfElements;

    if(size == capacity)
    {
        // Set new capacity
        CLR_RT_HeapBlock newArrayHB;
        
        // Protect value from GC, in case CreateInstance triggers one
        CLR_RT_HeapBlock valueHB; valueHB.SetObjectReference( value );
        CLR_RT_ProtectFromGC gc( valueHB );

        capacity *= 2;

        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( newArrayHB, capacity, g_CLR_RT_WellKnownTypes.m_Object ));

        array = newArrayHB.DereferenceArray();

        CopyTo( array, 0 );

        tail = size;

        SetArray( array );
        SetHead ( 0     );
        SetTail ( tail  );
    }

    ((CLR_RT_HeapBlock*)array->GetElement( tail ))->SetObjectReference( value );

    SetTail( (tail + 1) % capacity );

    SetSize( size + 1 );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_AppDomain::CreateDomain___STATIC__SystemAppDomain__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();
   
    CLR_RT_AppDomain*    appDomain   = NULL;        
    CLR_RT_HeapBlock&    pArgs       = stack.Arg0();    
    CLR_RT_HeapBlock     res; res.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC gc( res );
    LPCSTR               szName;

    szName = pArgs.RecoverString(); FAULT_ON_NULL(szName);
    
    TINYCLR_CHECK_HRESULT(CLR_RT_AppDomain::CreateInstance( szName, appDomain ));

    //load mscorlib
    TINYCLR_CHECK_HRESULT(appDomain->LoadAssembly( g_CLR_RT_TypeSystem.m_assemblyMscorlib ));        
    //load Native
    TINYCLR_CHECK_HRESULT(appDomain->LoadAssembly( g_CLR_RT_TypeSystem.m_assemblyNative   ));
    
    TINYCLR_CHECK_HRESULT(appDomain->GetManagedObject( res ));

    //Marshal the new AD to the calling AD.
    TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.GetCurrentAppDomain()->MarshalObject( res, res, appDomain ));

    stack.PushValueAndAssign( res );

    TINYCLR_CLEANUP();

    if(FAILED(hr))
    {
        if(appDomain)
        {
            appDomain->DestroyInstance();
        }        
    }

    TINYCLR_CLEANUP_END();
}
HRESULT Library_spot_native_Microsoft_SPOT_CryptoState::Buffer::Allocate( CLR_RT_HeapBlock& ref, int size )
{
    TINYCLR_HEADER();

    ref.SetObjectReference( NULL );

    if(size)
    {
        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( ref, size, g_CLR_RT_WellKnownTypes.m_UInt8 ));

        m_array = ref.DereferenceArray();
    }
    else
    {
        m_array = NULL;
    }

    m_offset = 0;
    m_count  = size;

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::MarshalSockAddress( CLR_RT_HeapBlock& blkDst, const struct SOCK_sockaddr* addrSrc, CLR_UINT32 addrLenSrc )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* arr = NULL;

    CLR_RT_HeapBlock blkArr; blkArr.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC gc( blkArr );
        
    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( blkArr, addrLenSrc, g_CLR_RT_WellKnownTypes.m_UInt8 ));
    
    arr = blkArr.DereferenceArray();

    _ASSERTE(arr);

    memcpy( arr->GetFirstElement(), addrSrc, addrLenSrc );

    _ASSERTE(blkDst.DataType() == DATATYPE_BYREF || blkDst.DataType() == DATATYPE_ARRAY_BYREF);

    TINYCLR_CHECK_HRESULT(blkArr.StoreToReference( blkDst, 0 ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Text_UTF8Encoding::Helper__GetChars(CLR_RT_StackFrame& stack, bool fIndexed)
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    LPSTR szText;
    CLR_RT_HeapBlock ref;
    ref.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC gc( ref );
    CLR_RT_HeapBlock_Array* pArrayBytes = stack.Arg1().DereferenceArray();
    CLR_INT32               byteIdx     = fIndexed ? stack.Arg2().NumericByRef().s4 : 0;
    CLR_INT32               byteCnt     = fIndexed ? stack.Arg3().NumericByRef().s4 : pArrayBytes->m_numOfElements;
    CLR_RT_HeapBlock_Array* pArrayBytesCopy;
    CLR_RT_HeapBlock_Array* arrTmp;
    int cBytesCopy;

    FAULT_ON_NULL(pArrayBytes);

    _ASSERTE(pArrayBytes->m_typeOfElement == DATATYPE_U1);

    if((byteIdx + byteCnt) > (CLR_INT32)pArrayBytes->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    cBytesCopy = byteCnt+1;

    /* Copy the array to a temporary buffer to create a zero-terminated string */
    TINYCLR_CHECK_HRESULT( CLR_RT_HeapBlock_Array::CreateInstance( ref, cBytesCopy, g_CLR_RT_WellKnownTypes.m_UInt8 ));

    pArrayBytesCopy = ref.DereferenceArray();
    szText = (LPSTR)pArrayBytesCopy->GetFirstElement();

    hal_strncpy_s( szText, cBytesCopy, (LPSTR)pArrayBytes->GetElement(byteIdx), byteCnt );

    TINYCLR_CHECK_HRESULT(Library_corlib_native_System_String::ConvertToCharArray( szText, stack.PushValueAndClear(), arrTmp, 0, -1 ));

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_Queue::Dequeue( CLR_RT_HeapBlock*& value )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* array   = GetArray();
    CLR_INT32               size    = GetSize();
    CLR_INT32               head    = Head();
    CLR_RT_HeapBlock*       removed;

    if(size == 0) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION);

    removed = (CLR_RT_HeapBlock*)array->GetElement( head );

    value = removed->Dereference();

    removed->SetObjectReference( NULL );

    SetHead( (head + 1) % array->m_numOfElements );
    
    SetSize( size - 1 );

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_XmlNameTable::AddEntry( CLR_RT_HeapBlock_String*& str, CLR_INT32 hashCode )
{
    TINYCLR_HEADER();
    
    CLR_RT_HeapBlock                     newEntryHB;
    CLR_RT_HeapBlock_XmlNameTable_Entry* newEntry;
    CLR_RT_HeapBlock*                    entryHB;

    CLR_INT32                            count;  

    // create a new instance of the Entry object
    TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( newEntryHB, g_CLR_RT_WellKnownTypes.m_XmlNameTable_Entry ));
    
    newEntry = (CLR_RT_HeapBlock_XmlNameTable_Entry*)newEntryHB.Dereference();
    
    // attach it to the front of the bucket
    entryHB = (CLR_RT_HeapBlock*)GetEntries()->GetElement( GetMask() & hashCode );

    newEntry->SetStr( str );
    newEntry->SetHashCode( hashCode );
    newEntry->SetNext( (CLR_RT_HeapBlock_XmlNameTable_Entry*)entryHB->Dereference() );
    
    entryHB->SetObjectReference( newEntry );

    count = GetCount() + 1;
    
    SetCount( count );

    // if we reach the threshold, we'll grow the buckets
    if(count == GetMask())
    {
        Grow();
    }

    TINYCLR_NOCLEANUP();
}
Example #13
0
void CLR_RT_StackFrame::Pop()
{
    NATIVE_PROFILE_CLR_CORE();

#if defined(TINYCLR_PROFILE_NEW_CALLS)
    {
        //
        // This passivates any outstanding handler.
        //
        CLR_PROF_HANDLER_CALLCHAIN(pm2,m_callchain);

        m_callchain.Leave();
    }
#endif

#if defined(TINYCLR_PROFILE_NEW_CALLS)
    g_CLR_PRF_Profiler.RecordFunctionReturn( m_owningThread, m_callchain );
#endif

#if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING)
    if(m_owningThread->m_fHasJMCStepper || (m_flags & c_HasBreakpoint))
    {
        g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Pop( this, false );
    }
#endif

    const CLR_UINT32 c_flagsToCheck = CLR_RT_StackFrame::c_CallOnPop | CLR_RT_StackFrame::c_Synchronized | CLR_RT_StackFrame::c_SynchronizedGlobally | CLR_RT_StackFrame::c_NativeProfiled;

    if(m_flags & c_flagsToCheck)
    {
        if(m_flags & CLR_RT_StackFrame::c_CallOnPop)
        {
            m_flags |= CLR_RT_StackFrame::c_CalledOnPop;

            if(m_nativeMethod)
            {
                (void)m_nativeMethod( *this );
            }
        }

        if(m_flags & CLR_RT_StackFrame::c_Synchronized)
        {
            m_flags &= ~CLR_RT_StackFrame::c_Synchronized;

            (void)HandleSynchronized( false, false );
        }

        if(m_flags & CLR_RT_StackFrame::c_SynchronizedGlobally)
        {
            m_flags &= ~CLR_RT_StackFrame::c_SynchronizedGlobally;

            (void)HandleSynchronized( false, true );
        }

#if defined(ENABLE_NATIVE_PROFILER)
        if(m_flags & CLR_RT_StackFrame::c_NativeProfiled)
        {
            m_owningThread->m_fNativeProfiled = false;
            m_flags &= ~CLR_RT_StackFrame::c_NativeProfiled;
            Native_Profiler_Stop();
        }
#endif
    }

    CLR_RT_StackFrame* caller = Caller();

    if(caller->Prev() != NULL)
    {
#if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING)
        if(caller->m_flags & CLR_RT_StackFrame::c_HasBreakpoint)
        {
            g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Step( caller, caller->m_IP );
        }
#endif

        //
        // Constructors are slightly different, they push the 'this' pointer back into the caller stack.
        //
        // This is to enable the special case for strings, where the object can be recreated by the constructor...
        //
        if(caller->m_flags & CLR_RT_StackFrame::c_ExecutingConstructor)
        {
            CLR_RT_HeapBlock& src = this  ->Arg0              (     );
            CLR_RT_HeapBlock& dst = caller->PushValueAndAssign( src );

            dst.Promote();

            //
            // Undo the special "object -> reference" hack done by CEE_NEWOBJ.
            //
            if(dst.DataType() == DATATYPE_BYREF)
            {
                dst.ChangeDataType( DATATYPE_OBJECT );
            }

            caller->m_flags &= ~CLR_RT_StackFrame::c_ExecutingConstructor;

            _ASSERTE((m_flags & CLR_RT_StackFrame::c_AppDomainTransition) == 0);
        }
        else
        {   //Note that ExecutingConstructor is checked on 'caller', whereas the other two flags are checked on 'this'
            const CLR_UINT32 c_moreFlagsToCheck = CLR_RT_StackFrame::c_PseudoStackFrameForFilter | CLR_RT_StackFrame::c_AppDomainTransition;

            if(m_flags & c_moreFlagsToCheck)
            {
                if(m_flags & CLR_RT_StackFrame::c_PseudoStackFrameForFilter)
                {
                    //Do nothing here. Pushing return values onto stack frames that don't expect them are a bad idea.
                }
#if defined(TINYCLR_APPDOMAINS)
                else if((m_flags & CLR_RT_StackFrame::c_AppDomainTransition) != 0)
                {
                    (void)PopAppDomainTransition();
                }
#endif
            }
            else //!c_moreFlagsToCheck
            {
                //
                // Push the return, if any.
                //
                if(m_call.m_target->retVal != DATATYPE_VOID)
                {
                    if(m_owningThread->m_currentException.Dereference() == NULL)
                    {
                        CLR_RT_HeapBlock& src = this  ->TopValue          (     );
                        CLR_RT_HeapBlock& dst = caller->PushValueAndAssign( src );

                        dst.Promote();
                    }
                }
            }
        }
    }
#if defined(TINYCLR_ENABLE_SOURCELEVELDEBUGGING)
    else
    {
        int idx = m_owningThread->m_scratchPad;

        if(idx >= 0)
        {
            CLR_RT_HeapBlock_Array* array = g_CLR_RT_ExecutionEngine.m_scratchPadArray;

            if(array && array->m_numOfElements > (CLR_UINT32)idx)
            {
                CLR_RT_HeapBlock* dst       = (CLR_RT_HeapBlock*)array->GetElement( (CLR_UINT32)idx );
                CLR_RT_HeapBlock* exception = m_owningThread->m_currentException.Dereference();

                dst->SetObjectReference( NULL );

                if(exception != NULL)
                {
                    dst->SetObjectReference( exception );
                }
                else if(m_call.m_target->retVal != DATATYPE_VOID)
                {
                    CLR_RT_SignatureParser sig;
                    sig.Initialize_MethodSignature( this->m_call.m_assm, this->m_call.m_target );
                    CLR_RT_SignatureParser::Element res;
                    CLR_RT_TypeDescriptor           desc;

                    dst->Assign( this->TopValue() );

                    //Perform boxing, if needed.

                    //Box to the return value type
                    _SIDE_ASSERTE(SUCCEEDED(sig.Advance( res )));
                    _SIDE_ASSERTE(SUCCEEDED(desc.InitializeFromType( res.m_cls )));


                    if(c_CLR_RT_DataTypeLookup[ this->DataType() ].m_flags & CLR_RT_DataTypeLookup::c_OptimizedValueType
                            || desc.m_handlerCls.m_target->IsEnum()
                      )
                    {
                        if(FAILED(dst->PerformBoxing( desc.m_handlerCls )))
                        {
                            dst->SetObjectReference( NULL );
                        }
                    }
                }
            }
        }
    }
#endif

    //
    // We could be jumping outside of a nested exception handler.
    //

    m_owningThread->PopEH( this, NULL );


    //
    // If this StackFrame owns a SubThread, kill it.
    //
    {
        CLR_RT_SubThread* sth = (CLR_RT_SubThread*)m_owningSubThread->Next();

        if(sth->Next() && sth->m_owningStackFrame == this)
        {
            CLR_RT_SubThread::DestroyInstance( sth->m_owningThread, sth, CLR_RT_SubThread::MODE_IncludeSelf );
        }
    }

    g_CLR_RT_EventCache.Append_Node( this );
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::getaddrinfo___STATIC__VOID__STRING__BYREF_STRING__BYREF_SZARRAY_SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    LPCSTR szName = stack.Arg0().RecoverString();
    struct SOCK_addrinfo hints;
    struct SOCK_addrinfo* addr = NULL;
    struct SOCK_addrinfo* addrT;
    CLR_UINT32        cAddresses = 0;
    CLR_RT_HeapBlock* pAddress;
    CLR_INT32         timeout_ms = 30000;
    CLR_RT_HeapBlock  hbTimeout;
    CLR_INT32         ret;
    bool              fRes = true;
    CLR_INT64*        timeout;

    hbTimeout.SetInteger( timeout_ms );

    TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout ));

    do
    {
        memset( &hints, 0, sizeof(hints) );

        ret = SOCK_getaddrinfo( szName, NULL, &hints, &addr );

        if(ret == SOCK_SOCKET_ERROR)
        {
            if(SOCK_getlasterror() == SOCK_EWOULDBLOCK)
            {
                // non-blocking - allow other threads to run while we wait for handle activity
                TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes ));
            }
            else
            {
                break;
            }
        }
        else
        {
            break;
        }
    }
    while(fRes);
    
    // timeout expired
    if(!fRes)
    {
        ret = SOCK_SOCKET_ERROR;
        
        ThrowError( stack, SOCK_ETIMEDOUT );
    
        TINYCLR_SET_AND_LEAVE( CLR_E_PROCESS_EXCEPTION );
    }

    // getaddrinfo returns a winsock error code rather than SOCK_SOCKET_ERROR, so pass this on to the exception handling
    if(ret != 0)
    {
        ThrowError( stack, ret );
        TINYCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION);
    }

    {
        CLR_RT_HeapBlock  hbCanonicalName;
        CLR_RT_HeapBlock  hbAddresses;
        
        hbCanonicalName.SetObjectReference( NULL );
        CLR_RT_ProtectFromGC gc( hbCanonicalName );

        hbAddresses.SetObjectReference( NULL );
        CLR_RT_ProtectFromGC gc2( hbAddresses );

        for(int pass = 0; pass < 2; pass++)
        {                                    
            cAddresses = 0;

            for(addrT = addr; addrT != NULL; addrT = addrT->ai_next)
            {
                if(pass == 1)
                {
                    if(addrT->ai_canonname && addrT->ai_canonname[ 0 ])
                    {
                        //allocate return string
                        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbCanonicalName, addrT->ai_canonname ));
                        TINYCLR_CHECK_HRESULT(hbCanonicalName.StoreToReference( stack.Arg1(), 0 ));
                    }

                    //allocate address and store into array
                    pAddress = (CLR_RT_HeapBlock*)hbAddresses.DereferenceArray()->GetElement( cAddresses );

                    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( *pAddress, (CLR_UINT32)addrT->ai_addrlen, g_CLR_RT_WellKnownTypes.m_UInt8 ));

                    //copy address.
                    memcpy( pAddress->DereferenceArray()->GetFirstElement(), addrT->ai_addr, addrT->ai_addrlen );
                }
                                
                cAddresses++;
            }
                            
            if(pass == 0)
            {
                //allocate array of byte arrays
                CLR_RT_ReflectionDef_Index idx;

                idx.m_kind               = REFLECTION_TYPE;
                idx.m_levels             = 2;
                idx.m_data.m_type.m_data = g_CLR_RT_WellKnownTypes.m_UInt8.m_data;

                TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( hbAddresses, cAddresses, idx ));

                TINYCLR_CHECK_HRESULT(hbAddresses.StoreToReference( stack.Arg2(), 0 ));                
            }
        }    
    }

    stack.PopValue();       // Timeout
    
    TINYCLR_CLEANUP();

    if( addr ) SOCK_freeaddrinfo( addr );

    TINYCLR_CLEANUP_END();
}
Example #15
0
HRESULT CLR_RT_StackFrame::PopAppDomainTransition()
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    bool fException = false;
    CLR_RT_HeapBlock exception;
    CLR_RT_StackFrame* caller = this->Caller();

    exception.SetObjectReference( NULL );

    if(m_flags & CLR_RT_StackFrame::c_AppDomainInjectException)
    {
        //this is the last frame on the thread in a doomed AppDomain
        //Convert the current ThreadAbortException into an AppDomainUnloaded exception

        _ASSERTE(m_owningThread->m_flags & CLR_RT_Thread::TH_F_Aborted);
        _ASSERTE(m_owningThread->m_flags & CLR_RT_Thread::TH_F_ContainsDoomedAppDomain);
        _ASSERTE(m_owningThread->m_currentException.Dereference() != NULL);
        _ASSERTE(m_owningThread->m_currentException.Dereference()->ObjectCls().m_data == g_CLR_RT_WellKnownTypes.m_ThreadAbortException.m_data);
        _ASSERTE(!m_appDomain->IsLoaded());

        m_owningThread->m_flags &= ~(CLR_RT_Thread::TH_F_Aborted | CLR_RT_Thread::TH_F_ContainsDoomedAppDomain);

        hr = CLR_E_APPDOMAIN_EXITED;
    }
    else if(m_owningThread->m_currentException.Dereference() == NULL)
    {
        _ASSERTE((m_flags & CLR_RT_StackFrame::c_AppDomainInjectException) == 0);

        //Normal return.  No exception is in flight

        if(m_flags & CLR_RT_StackFrame::c_AppDomainMethodInvoke)
        {
            //  For dynamic invoke,
            //  we do not marshal byRef parameters back to the calling AppDomain
            //  The caller is a native method (MethodBase::Invoke), and does not have the args on it's eval stack.
        }
        else
        {
            int cArgs = m_call.m_target->numArgs;

            //First marshal the ref parameters
            TINYCLR_CHECK_HRESULT(caller->m_appDomain->MarshalParameters( &caller->m_evalStackPos[ -cArgs ], m_arguments, cArgs, true ));

            //Now, pop the caller's arguments off the eval stack
            caller->m_evalStackPos -= cArgs;
        }

        // Now, push the return, if any.
        if(m_call.m_target->retVal != DATATYPE_VOID)
        {
            CLR_RT_HeapBlock& dst = caller->PushValueAndClear();
            CLR_RT_HeapBlock& src = this  ->TopValue ();

            TINYCLR_CHECK_HRESULT(caller->m_appDomain->MarshalObject( src, dst ));

            dst.Promote();
        }
    }
    else //Exception
    {
        //Normal exceptions must be marshaled to the caller's AppDomain
        TINYCLR_CHECK_HRESULT(caller->m_appDomain->MarshalObject( m_owningThread->m_currentException, exception ));
        fException = true;
    }

    TINYCLR_CLEANUP();

    if(FAILED(hr) || fException)
    {
        if(FAILED(hr))
        {
            (void)Library_corlib_native_System_Exception::CreateInstance( exception, hr, caller );
        }

        m_owningThread->m_currentException.Assign( exception );
    }

    (void)g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( caller->m_appDomain );

    TINYCLR_CLEANUP_END();
}
Example #16
0
HRESULT CLR_RT_StackFrame::MakeCall( CLR_RT_MethodDef_Instance md, CLR_RT_HeapBlock* obj, CLR_RT_HeapBlock* args, int nArgs )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    const CLR_RECORD_METHODDEF* mdR        = md.m_target;
    bool                        fStatic    =(mdR->flags & CLR_RECORD_METHODDEF::MD_Static) != 0;
    int                         numArgs    = mdR->numArgs;
    int                         argsOffset = 0;
    CLR_RT_StackFrame*          stackSub;
    CLR_RT_HeapBlock            tmp;
    tmp.SetObjectReference( NULL );
    CLR_RT_ProtectFromGC        gc(tmp);

    if(mdR->flags & CLR_RECORD_METHODDEF::MD_Constructor)
    {
        CLR_RT_TypeDef_Instance owner;
        owner.InitializeFromMethod( md );

        _ASSERTE(obj == NULL);

        _SIDE_ASSERTE(owner.InitializeFromMethod( md ));

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObject( tmp, owner ));

        obj = &tmp;

        //
        // Make a copy of the object pointer.
        //
        PushValueAndAssign( tmp );
    }

    if(!fStatic)
    {
        FAULT_ON_NULL(obj);
        numArgs--;
        argsOffset = 1;
    }

    if(numArgs != nArgs) TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    //
    // In case the invoked method is abstract or virtual, resolve it to the correct method implementation.
    //
    if(mdR->flags & (CLR_RECORD_METHODDEF::MD_Abstract | CLR_RECORD_METHODDEF::MD_Virtual))
    {
        CLR_RT_TypeDef_Index   cls;
        CLR_RT_MethodDef_Index mdReal;

        _ASSERTE(obj);
        _ASSERTE(!fStatic);

        TINYCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractTypeIndexFromObject( *obj, cls ));

        if(g_CLR_RT_EventCache.FindVirtualMethod( cls, md, mdReal ) == false)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
        }

        md.InitializeFromIndex( mdReal );

        mdR = md.m_target;
    }

#if defined(TINYCLR_APPDOMAINS)

    if(!fStatic && obj->IsTransparentProxy())
    {
        TINYCLR_CHECK_HRESULT(CLR_RT_StackFrame::PushAppDomainTransition( m_owningThread, md, obj, args ));

        stackSub = m_owningThread->CurrentFrame();

        stackSub->m_flags |= CLR_RT_StackFrame::c_AppDomainMethodInvoke;
    }
    else
#endif
    {
        TINYCLR_CHECK_HRESULT(CLR_RT_StackFrame::Push( m_owningThread, md, md.m_target->numArgs ));

        stackSub = m_owningThread->CurrentFrame();

        if(!fStatic)
        {
            stackSub->m_arguments[ 0 ].Assign( *obj );
        }

        if(numArgs)
        {
            memcpy( &stackSub->m_arguments[ argsOffset ], args, sizeof(CLR_RT_HeapBlock) * numArgs );
        }
    }

    TINYCLR_CHECK_HRESULT(stackSub->FixCall());

    TINYCLR_SET_AND_LEAVE(CLR_E_RESTART_EXECUTION);

    TINYCLR_NOCLEANUP();
}
Example #17
0
HRESULT CLR_RT_StackFrame::HandleSynchronized( bool fAcquire, bool fGlobal )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock   refType;
    CLR_RT_HeapBlock*  obj;
    CLR_RT_HeapBlock   ref;
    CLR_RT_HeapBlock** ppGlobalLock;
    CLR_RT_HeapBlock*  pGlobalLock;

    if(fGlobal)
    {
        obj = &ref;

#if defined(TINYCLR_APPDOMAINS)
        //With AppDomains enabled, the global lock is no longer global.  It is only global wrt the AppDomain/
        //Do we need a GlobalGlobalLock? (an attribute on GloballySynchronized (GlobalAcrossAppDomain?)
        ppGlobalLock = &g_CLR_RT_ExecutionEngine.GetCurrentAppDomain()->m_globalLock;
#else
        ppGlobalLock = &g_CLR_RT_ExecutionEngine.m_globalLock;
#endif

        pGlobalLock = *ppGlobalLock;

        if(pGlobalLock)
        {
            obj->SetObjectReference( pGlobalLock );
        }
        else
        {
            //
            // Create an private object to implement global locks.
            //
            TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( *obj, g_CLR_RT_WellKnownTypes.m_Object ));

            *ppGlobalLock = obj->Dereference();
        }
    }
    else if(m_call.m_target->flags & CLR_RECORD_METHODDEF::MD_Static)
    {
        CLR_RT_TypeDef_Index idx;

        idx.Set( m_call.Assembly(), m_call.CrossReference().GetOwner() );

        refType.SetReflection( idx );

        obj = &refType;
    }
    else
    {
        obj = &Arg0();
    }

    if(fAcquire)
    {
        TINYCLR_SET_AND_LEAVE(g_CLR_RT_ExecutionEngine.LockObject( *obj, m_owningSubThread, TIMEOUT_INFINITE, false ));
    }
    else
    {
        TINYCLR_SET_AND_LEAVE(g_CLR_RT_ExecutionEngine.UnlockObject( *obj, m_owningSubThread ));
    }

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_Array::Copy( CLR_RT_HeapBlock_Array* arraySrc, int indexSrc, CLR_RT_HeapBlock_Array* arrayDst, int indexDst, int length )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    if(length)
    {
        int numElemSrc = arraySrc->m_numOfElements;
        int numElemDst = arrayDst->m_numOfElements;

        if(length   < 0                   ||
           indexSrc < 0                   ||
           indexDst < 0                   ||
           length + indexSrc > numElemSrc ||
           length + indexDst > numElemDst  )
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
        }

        //
        // Copy of an array on itself.
        //
        if(arraySrc == arrayDst && indexSrc == indexDst) TINYCLR_SET_AND_LEAVE(S_OK);

        if(arraySrc->SameHeader( *arrayDst ))
        {
            CLR_UINT8* dataSrc  = arraySrc->GetFirstElement();
            CLR_UINT8* dataDst  = arrayDst->GetFirstElement();
            CLR_UINT8  sizeElem = arraySrc->m_sizeOfElement;

            dataSrc += indexSrc * sizeElem;
            dataDst += indexDst * sizeElem;

            if(!arraySrc->m_fReference)
            {
                memmove( dataDst, dataSrc, length * sizeElem );
            }
            else
            {
                CLR_RT_HeapBlock* ptrSrc = (CLR_RT_HeapBlock*)dataSrc;
                CLR_RT_HeapBlock* ptrDst = (CLR_RT_HeapBlock*)dataDst;
                int               incr;

                if(arraySrc == arrayDst && ptrSrc < ptrDst)
                {
                    incr    =       -1;
                    ptrSrc += length-1;
                    ptrDst += length-1;
                }
                else
                {
                    incr = 1;
                }

                for(int i=0; i<length; i++, ptrSrc += incr, ptrDst += incr)
                {
                    TINYCLR_CHECK_HRESULT(ptrDst->Reassign( *ptrSrc ));
                }
            }
        }
        else if(arraySrc->m_fReference && arrayDst->m_fReference)
        {
            CLR_RT_TypeDescriptor descSrc;
            CLR_RT_TypeDescriptor descDst;
            CLR_RT_HeapBlock*     ptrSrc   = (CLR_RT_HeapBlock*)arraySrc->GetElement( indexSrc );
            CLR_RT_HeapBlock*     ptrDst   = (CLR_RT_HeapBlock*)arrayDst->GetElement( indexDst );
            
            TINYCLR_CHECK_HRESULT(descDst.InitializeFromObject( *arrayDst )); descDst.GetElementType( descDst );

            for(int i=0; i<length; i++, ptrSrc++, ptrDst++)
            {
                if(ptrSrc->DataType() == DATATYPE_OBJECT && ptrSrc->Dereference() == NULL)
                {
                    ;
                }
                else
                {
                    TINYCLR_CHECK_HRESULT(descSrc.InitializeFromObject( *ptrSrc ));

                    if(CLR_RT_ExecutionEngine::IsInstanceOf( descSrc, descDst ) == false)
                    {
                        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_CAST);
                    }
                }

                TINYCLR_CHECK_HRESULT(ptrDst->Reassign( *ptrSrc ));
            }
        }
        else
        {
            CLR_RT_TypeDescriptor descSrc;
            CLR_RT_TypeDescriptor descDst;
            CLR_RT_HeapBlock      ref;
            CLR_RT_HeapBlock      elem; elem.SetObjectReference( NULL );
            CLR_RT_ProtectFromGC  gc( elem ); 

            TINYCLR_CHECK_HRESULT(descDst.InitializeFromObject( *arrayDst )); descDst.GetElementType( descDst );

            for(int i=0; i<length; i++)
            {
                ref.InitializeArrayReferenceDirect( *arraySrc, indexSrc++ ); TINYCLR_CHECK_HRESULT(elem.LoadFromReference( ref ));

                if(elem.DataType() == DATATYPE_OBJECT && elem.Dereference() == NULL)
                {
                    ;
                }
                else
                {
                    TINYCLR_CHECK_HRESULT(descSrc.InitializeFromObject( elem ));

                    if(CLR_RT_ExecutionEngine::IsInstanceOf( descSrc, descDst ) == false)
                    {
                        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_CAST);
                    }
                }

                ref.InitializeArrayReferenceDirect( *arrayDst, indexDst++ ); TINYCLR_CHECK_HRESULT(elem.StoreToReference( ref, 0 ));
            }
        }
    }

    TINYCLR_NOCLEANUP();
}
HRESULT CLR_RT_HeapBlock_Delegate_List::Change( CLR_RT_HeapBlock& reference, CLR_RT_HeapBlock& delegateSrc, CLR_RT_HeapBlock& delegateTarget, bool fCombine, bool fWeak )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Delegate_List* dlgListSrc;
    CLR_RT_HeapBlock_Delegate_List* dlgListDst;
    CLR_RT_HeapBlock_Delegate*      dlg;
    CLR_RT_HeapBlock*               newDlgs;
    CLR_RT_HeapBlock*               oldDlgs;
    CLR_UINT32                      oldNum;
    CLR_UINT32                      newNum;

    CLR_UINT32 num = 0;

    reference.SetObjectReference( NULL );

    if(delegateSrc   .DataType() != DATATYPE_OBJECT ||
       delegateTarget.DataType() != DATATYPE_OBJECT  )
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
    }

    dlg = delegateTarget.DereferenceDelegate();

    if(dlg == NULL)
    {
        reference.SetObjectReference( delegateSrc.DereferenceDelegate() );
        TINYCLR_SET_AND_LEAVE(S_OK);
    }

    if(dlg->DataType() == DATATYPE_DELEGATELIST_HEAD)
    {
        CLR_RT_HeapBlock     intermediate; intermediate.Assign( delegateSrc );
        CLR_RT_ProtectFromGC gc( intermediate );

        dlgListDst = (CLR_RT_HeapBlock_Delegate_List*)dlg;
        newDlgs    = dlgListDst->GetDelegates();

        for(num=0; num<dlgListDst->m_length; num++, newDlgs++)
        {
            if(newDlgs->DataType() == DATATYPE_OBJECT && newDlgs->DereferenceDelegate() != NULL) // The delegate could have been GC'ed.
            {
                TINYCLR_CHECK_HRESULT(Change( reference, intermediate, *newDlgs, fCombine, fWeak ));

                intermediate.Assign( reference );
            }
        }
    }
    else
    {
        dlgListSrc = delegateSrc.DereferenceDelegateList();
        if(dlgListSrc == NULL)
        {
            oldDlgs = NULL;
            oldNum  = 0;
        }
        else
        {
            switch(dlgListSrc->DataType())
            {
            case DATATYPE_DELEGATE_HEAD:
                oldDlgs = &delegateSrc;
                oldNum  = 1;
                break;

            case DATATYPE_DELEGATELIST_HEAD:
                oldDlgs = dlgListSrc->GetDelegates();
                oldNum  = dlgListSrc->m_length;
                break;

            default:
                TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
            }
        }

        if(fCombine)
        {
            if(oldNum == 0 && fWeak == false)
            {
                //
                // Empty input list, copy the delegate.
                //
                reference.Assign( delegateTarget );
                TINYCLR_SET_AND_LEAVE(S_OK);
            }

            //--//

            newNum = oldNum + 1;
        }
        else
        {
            for(num=0, newDlgs=oldDlgs; num<oldNum; num++, newDlgs++)
            {
                CLR_RT_HeapBlock_Delegate* ptr = newDlgs->DereferenceDelegate();
                if(ptr)
                {
                    if( ptr->DelegateFtn().m_data   == dlg->DelegateFtn().m_data   &&
                        ptr->m_object.Dereference() == dlg->m_object.Dereference()  )
                    {
                        break;
                    }
                }
            }

            if(num == oldNum)
            {
                reference.Assign( delegateSrc ); // Nothing to remove.
                TINYCLR_SET_AND_LEAVE(S_OK);
            }

            if(oldNum == 2 && (dlgListSrc->m_flags & CLR_RT_HeapBlock_Delegate_List::c_Weak) == 0)
            {
                reference.Assign( oldDlgs[ 1-num ] ); // Convert from a list to delegate.
                TINYCLR_SET_AND_LEAVE(S_OK);
            }

            if(oldNum == 1)
            {
                reference.SetObjectReference( NULL ); // Oops, empty delegate...
                TINYCLR_SET_AND_LEAVE(S_OK);
            }

            //--//

            newNum = oldNum - 1;
        }

        TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Delegate_List::CreateInstance( dlgListDst, newNum ));

        dlgListDst->m_cls = dlg->m_cls;

        newDlgs = dlgListDst->GetDelegates();

        if(fCombine)
        {
            newDlgs = dlgListDst->CopyAndCompress( oldDlgs, newDlgs, oldNum );

            newDlgs->Assign( delegateTarget );
        }
        else
        {
            newDlgs = dlgListDst->CopyAndCompress( oldDlgs      , newDlgs,          num++ );
            newDlgs = dlgListDst->CopyAndCompress( oldDlgs + num, newDlgs, oldNum - num   );
        }

        dlgListDst->m_flags = (dlgListSrc && oldNum > 1) ? dlgListSrc->m_flags : 0;

        if(fWeak) dlgListDst->m_flags |= CLR_RT_HeapBlock_Delegate_List::c_Weak;

        reference.SetObjectReference( dlgListDst );
    }

    TINYCLR_NOCLEANUP();
}