HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_AnalogInput::Uninitialize___STATIC__VOID__MicrosoftSPOTHardwareCpuAnalogChannel( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();
    
    ::AD_Uninitialize((ANALOG_CHANNEL)stack.Arg0().NumericByRef().s4);
    
    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::Open___STATIC__BOOLEAN__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32 handle = stack.Arg0().NumericByRef().s4;

    stack.SetResult_I4(MFUpdate_Open(handle));

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Threading_Monitor::Exit___STATIC__VOID__OBJECT( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_StackFrame* caller = NULL;

    if(stack.Arg0().Dereference() == NULL)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_ARGUMENT_NULL);
    }

    caller = stack.Caller();
    FAULT_ON_NULL(caller); // We need to set the constraint on the caller, not on us...

    TINYCLR_SET_AND_LEAVE(g_CLR_RT_ExecutionEngine.UnlockObject( stack.Arg0(), caller->m_owningSubThread ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::DeleteUpdate___STATIC__VOID__I4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32 handle = stack.Arg0().NumericByRef().s4;

    MFUpdate_Delete(handle);

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::SecureAccept___STATIC__VOID__I4__OBJECT( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_INT32         sslContext = stack.Arg0().NumericByRef().s4;
    CLR_RT_HeapBlock* socket     = stack.Arg1().Dereference();
    CLR_INT32         timeout_ms = -1; // wait forever
    CLR_RT_HeapBlock  hbTimeout;

    int        result = 0;    
    CLR_INT32  handle;
    bool       fRes = true;
    CLR_INT64 *timeout;

    FAULT_ON_NULL(socket);

    handle = socket[ Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::FIELD__m_Handle ].NumericByRef().s4;

    /* Because we could have been a rescheduled call due to a prior call that would have blocked, we need to see
     * if our handle has been shutdown before continuing. */
    if (handle == Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::DISPOSED_HANDLE)
    {
        ThrowError(stack, CLR_E_OBJECT_DISPOSED);
        TINYCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION);
    }


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


    // first make sure we have data to read or ability to write
    while(true)
    {
        result = SSL_Accept( handle, sslContext );

        if(result == SOCK_EWOULDBLOCK || result == SOCK_TRY_AGAIN)
        {
            // non-blocking - allow other threads to run while we wait for socket activity
            TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes ));
        }
        else
        {
            break;
        }
    }

    stack.PopValue();       // Timeout

    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Reflection::IsTypeLoaded___STATIC__BOOLEAN__mscorlibSystemType( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_TypeDef_Instance inst;

    stack.SetResult_Boolean( CLR_RT_ReflectionDef_Index::Convert( stack.Arg0(), inst, NULL ) );

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Math::Floor___STATIC__R8__R8( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_INT64 d = stack.Arg0().NumericByRefConst().r8;
    CLR_INT64 res = (CLR_INT64)( d  & (~CLR_RT_HeapBlock::HB_DoubleMask) );
    stack.SetResult_I8( res );

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::poll___STATIC__BOOLEAN__OBJECT__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock* socket = stack.Arg0().Dereference();
    CLR_INT32 handle;
    CLR_INT32 mode       = stack.Arg1().NumericByRef().s4;    
    CLR_INT32 timeout_us = stack.Arg2().NumericByRef().s4;
    
    CLR_RT_HeapBlock hbTimeout;
    CLR_INT32 timeout_ms;

    CLR_INT32 res = 0;
    bool fRes     = true;

    CLR_INT64* timeout;

    FAULT_ON_NULL(socket);
    handle = socket[ FIELD__m_Handle ].NumericByRef().s4;

    /* Because we could have been a rescheduled call due to a prior call that would have blocked, we need to see
     * if our handle has been shutdown before continuing. */
    if (handle == DISPOSED_HANDLE)
    {
        ThrowError( stack, CLR_E_OBJECT_DISPOSED );
        TINYCLR_SET_AND_LEAVE (CLR_E_PROCESS_EXCEPTION);
    }


    if(timeout_us < 0) timeout_ms = -1;
    else               timeout_ms = timeout_us / 1000;

    hbTimeout.SetInteger( timeout_ms );

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

    while(fRes)
    {
        res = Helper__SelectSocket( handle, mode );

        if(res != 0) break;

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes ));
    }

    stack.PopValue(); //timer

    TINYCLR_CHECK_HRESULT(ThrowOnError( stack, res ));

    stack.SetResult_Boolean( res == 1 );   

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_AnalogInput::Initialize___STATIC__VOID__MicrosoftSPOTHardwareCpuAnalogChannel__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();
    
    bool fRes = ::AD_Initialize((ANALOG_CHANNEL)stack.Arg0().NumericByRef().s4, stack.Arg1().NumericByRef().s4) != 0;
    
    TINYCLR_SET_AND_LEAVE(fRes ? S_OK : CLR_E_FAIL);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_RuntimeFieldInfo::get_Name___STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_FieldDef_Instance fd; if(GetFieldDescriptor( stack, stack.Arg0(), fd ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE);

    TINYCLR_SET_AND_LEAVE(CLR_RT_HeapBlock_String::CreateInstance( stack.PushValue(), fd.m_target->name, fd.m_assm ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Hardware_Utility::Piezo___STATIC__VOID__U4__U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock* pArgs = &(stack.Arg0());

    ::Piezo_Tone( pArgs[ 0 ].NumericByRef().u4, pArgs[ 1 ].NumericByRef().u4 );

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Math::Cosh___STATIC__R8__R8( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    double d = stack.Arg0().NumericByRefConst().r8;
    double res = System::Math::Cosh( d );

    stack.SetResult_R8( res );

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Double::CompareTo___STATIC__I4__R8__R8( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_INT64 left  = stack.Arg0().NumericByRef().s8;
    CLR_INT64 right = stack.Arg1().NumericByRef().s8;

    stack.SetResult_I4((left < right) ? -1 : (left > right) ? 1 : 0);

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Double::IsPositiveInfinity___STATIC__BOOLEAN__R8( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    double d = stack.Arg0().NumericByRefConst().r8;
    bool res = System::Double::IsPositiveInfinity( d );

    stack.SetResult_Boolean( res );    

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Reflection_Assembly::Load___STATIC__SystemReflectionAssembly__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* array = NULL;
    CLR_RT_Assembly*        assm  = NULL;
    CLR_RT_HeapBlock&       top   = stack.PushValueAndClear();
    CLR_RECORD_ASSEMBLY*    header;

    array = stack.Arg0().DereferenceArray(); FAULT_ON_NULL(array);

    header = (CLR_RECORD_ASSEMBLY*)array->GetFirstElement();

    if(header->GoodAssembly())
    {
        //
        // Sorry, you'll have to reboot to load this assembly.
        //
        if(header->flags & CLR_RECORD_ASSEMBLY::c_Flags_NeedReboot)
        {
            TINYCLR_SET_AND_LEAVE(CLR_E_BUSY);
        }

        TINYCLR_CHECK_HRESULT(CLR_RT_Assembly::CreateInstance( header, assm ));

        assm->m_pFile = array;

        g_CLR_RT_TypeSystem.Link( assm );

        TINYCLR_CHECK_HRESULT(g_CLR_RT_TypeSystem.ResolveAll         ());
        TINYCLR_CHECK_HRESULT(g_CLR_RT_TypeSystem.PrepareForExecution());
    }

    if(assm)
    {
        CLR_RT_Assembly_Index idx; idx.Set( assm->m_idx );

        top.SetReflection( idx );
    }

    TINYCLR_CLEANUP();

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

    TINYCLR_CLEANUP_END();
}
HRESULT Library_spot_native_Microsoft_SPOT_Hardware_Utility::CombineArrays___STATIC__SZARRAY_U1__SZARRAY_U1__I4__I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock* args = &stack.Arg0();

    TINYCLR_SET_AND_LEAVE(CombineArrays( stack, args[ 0 ], args[ 1 ].NumericByRefConst().s4, args[ 2 ].NumericByRefConst().s4 ,
                                                args[ 3 ], args[ 4 ].NumericByRefConst().s4, args[ 5 ].NumericByRefConst().s4 ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Threading_WaitHandle::WaitMultiple___STATIC__I4__SZARRAY_SystemThreadingWaitHandle__I4__BOOLEAN__BOOLEAN( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Array* arr = stack.Arg0().DereferenceArray();  FAULT_ON_NULL(arr);

    TINYCLR_CHECK_HRESULT(Wait( stack, stack.Arg1(), stack.Arg2(), (CLR_RT_HeapBlock*)arr->GetFirstElement(), arr->m_numOfElements, stack.Arg3().NumericByRef().s1 == 1 ));
    
    stack.SetResult_I4( stack.m_owningThread->m_waitForObject_Result );

    TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_BitConverter::DoubleToInt64Bits___STATIC__I8__R8( CLR_RT_StackFrame& stack )
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

	double input;
	input = stack.Arg0().NumericByRefConst().r8;
	__int64* p;
	p = reinterpret_cast<__int64*>(&input);
	stack.SetResult_I8(*p);

	TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_BitConverter::GetBytes___STATIC__SZARRAY_U1__R8(CLR_RT_StackFrame& stack)
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

#if !defined(TINYCLR_EMULATED_FLOATINGPOINT)
	double input = stack.Arg0().NumericByRefConst().r8;
#else
	CLR_INT64 input = stack.Arg0().NumericByRefConst().r8;
#endif

	TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(stack.PushValueAndClear(), 8, g_CLR_RT_WellKnownTypes.m_UInt8));
	{
		BYTE* p = stack.TopValue().DereferenceArray()->GetFirstElement();
#if !defined(TINYCLR_EMULATED_FLOATINGPOINT)
		*reinterpret_cast<double*>(p) = input;
#else
		*reinterpret_cast<CLR_INT64*>(p) = input;
#endif
	}
	TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::ExitSecureContext___STATIC__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    TINYCLR_HEADER();

    CLR_INT32 sslContext = stack.Arg0().NumericByRef().s4;

    int result = SSL_ExitContext( sslContext ) == TRUE ? 0 : -1;

    stack.SetResult_I4( result );

    TINYCLR_NOCLEANUP_NOLABEL();
}
static HRESULT ComputeSinCos( CLR_RT_StackFrame& stack, bool fSin )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    int index = (stack.Arg0().NumericByRef().s4 % 360) / 6; if(index < 0) index += 60;

    const CLR_RADIAN& rec = c_CLR_radians[ index ];

    stack.SetResult_I4( (int)(fSin ? rec.sin : rec.cos) );

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_Threading_Monitor::Enter___STATIC__VOID__OBJECT( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_StackFrame* caller = NULL;

    if(stack.Arg0().Dereference() == NULL)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_ARGUMENT_NULL);
    }

    switch(stack.m_customState)
    {
    case 0:
    {
        caller = stack.Caller();
        FAULT_ON_NULL(caller); // We need to set the constraint on the caller, not on us...

        hr = g_CLR_RT_ExecutionEngine.LockObject( stack.Arg0(), caller->m_owningSubThread, TIMEOUT_INFINITE, false );
        if(hr == CLR_E_THREAD_WAITING)
        {
            stack.m_customState = 1;
        }

        TINYCLR_LEAVE();
    }
    break;

    case 1:
        TINYCLR_SET_AND_LEAVE(S_OK);
        break;

    default:
        TINYCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_update_native_Microsoft_SPOT_MFUpdate_MFNativeUpdate::Authenticate___STATIC__BOOLEAN__I4__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER();

    CLR_INT32               handle  = stack.Arg0().NumericByRef().s4;
    CLR_RT_HeapBlock_Array* paArgs  = stack.Arg1().DereferenceArray();
    CLR_UINT8*              pArgs   = paArgs == NULL ? NULL : paArgs->GetFirstElement();
    CLR_INT32               argsLen = paArgs == NULL ? 0    : paArgs->m_numOfElements;

    stack.SetResult_Boolean(TRUE == MFUpdate_Authenticate(handle, pArgs, argsLen));

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_Cpu::set_GlitchFilterTime___STATIC__VOID__mscorlibSystemTimeSpan( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();

    CLR_INT64 val = (CLR_INT64_TEMP_CAST) stack.Arg0().NumericByRef().s8 / TIME_CONVERSION__TO_MILLISECONDS;

    if(!::CPU_GPIO_SetDebounce( val ))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_hardware_native_Microsoft_SPOT_Hardware_AnalogOutput::Initialize___STATIC__VOID__MicrosoftSPOTHardwareCpuAnalogOutputChannel__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_HARDWARE();
    TINYCLR_HEADER();
    
    DA_CHANNEL channel = (DA_CHANNEL)stack.Arg0().NumericByRef().s4;
    INT32 precisionInBits = stack.Arg1().NumericByRef().s4;
    
    bool fRes = ::DA_Initialize(channel, precisionInBits) != 0;
    
    TINYCLR_SET_AND_LEAVE(fRes ? S_OK : CLR_E_FAIL);

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_native_Microsoft_SPOT_Debug::Print___STATIC__VOID__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    LPCSTR szText0 = stack.Arg0().RecoverString();

    if(!szText0) szText0 = "<null>";

    CLR_Debug::Emit( szText0, -1 );
    CLR_Debug::Emit( "\r\n" , -1 );

    TINYCLR_NOCLEANUP_NOLABEL();
}
HRESULT Library_corlib_native_System_BitConverter::GetBytes___STATIC__SZARRAY_U1__I4( CLR_RT_StackFrame& stack )
{
	NATIVE_PROFILE_CLR_CORE();
	TINYCLR_HEADER();

	int input = stack.Arg0().NumericByRefConst().s4;

	TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(stack.PushValueAndClear(), 4, g_CLR_RT_WellKnownTypes.m_UInt8));
	BYTE* p;
	p  = stack.TopValue().DereferenceArray()->GetFirstElement();
	*reinterpret_cast<int*>(p) = input;

	TINYCLR_NOCLEANUP();
}
HRESULT Library_corlib_native_System_Reflection_MethodBase::get_Name___STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_MethodDef_Instance md;
    CLR_RT_HeapBlock*         hbMeth  = stack.Arg0().Dereference();

    TINYCLR_CHECK_HRESULT(GetMethodDescriptor( stack, *hbMeth, md ));

    TINYCLR_SET_AND_LEAVE(CLR_RT_HeapBlock_String::CreateInstance( stack.PushValue(), md.m_target->name, md.m_assm ));

    TINYCLR_NOCLEANUP();
}
HRESULT Library_spot_Time_native_Microsoft_SPOT_Time_TimeService::Update___STATIC__MicrosoftSPOTTimeTimeServiceStatus__U4__U4( CLR_RT_StackFrame& stack )
{
    TINYCLR_HEADER(); 

    CLR_RT_HeapBlock* managedStatus = NULL;  

    UINT32 serverIP  = stack.Arg0().NumericByRef().u4;
    UINT32 tolerance = stack.Arg1().NumericByRef().u4;    

    TimeService_Status status;

    hr = TimeService_Update( serverIP, tolerance, &status );

    if(hr == CLR_E_RESCHEDULE) 
    {
        TINYCLR_LEAVE();
    }
    else 
    {
        CLR_RT_HeapBlock& top = stack.PushValueAndClear();

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( top, g_CLR_RT_WellKnownTypes.m_TimeServiceStatus ));
        
        managedStatus = top.Dereference();

        managedStatus[ ManagedStatus::FIELD__Flags            ].SetInteger( status.Flags );
        managedStatus[ ManagedStatus::FIELD__SyncSourceServer ].SetInteger( status.ServerIP );
        managedStatus[ ManagedStatus::FIELD__SyncTimeOffset   ].SetInteger( status.SyncOffset );
        managedStatus[ ManagedStatus::FIELD__TimeUTC          ].SetInteger( status.CurrentTimeUTC );
    }

    TINYCLR_CLEANUP();

    // we are not throwing any exception, we are instead communicating the result through the TimeServiceStatus object we return
    // if the operation did not completed, we need to reschedule this call though
    switch(hr)
    {
        case CLR_E_RESCHEDULE:
            break;
        case CLR_E_TIMEOUT:
        case CLR_E_FAIL:
        default:
            // swallow error
            hr = S_OK; 
            break;
    }

    TINYCLR_CLEANUP_END();
}
HRESULT Library_corlib_native_System_Delegate::get_Target___OBJECT( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_Delegate* dlg = stack.Arg0().DereferenceDelegate();

    dlg = GetLastDelegate( dlg ); if(!dlg) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);

    {
        stack.PushValueAndAssign( dlg->m_object );
    }

    TINYCLR_NOCLEANUP();
}