Skip to content

Commit

Permalink
DateTime and TimeSpan are not handled as primitive types
Browse files Browse the repository at this point in the history
- Remove these throughout the code base.
- Add DateTime::NewObject and rework code accordingly.
- Update data type lookup for DateTime and TimeSpan so they end up as value type types.
  • Loading branch information
josesimoes committed Oct 11, 2023
1 parent 639afd8 commit 4b07c76
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 164 deletions.
1 change: 1 addition & 0 deletions src/CLR/CorLib/corlib_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ struct Library_corlib_native_System_DateTime

//--//

static CLR_INT64 *NewObject(CLR_RT_StackFrame &stack);
static CLR_INT64 *GetValuePtr(CLR_RT_StackFrame &stack);
static CLR_INT64 *GetValuePtr(CLR_RT_HeapBlock &ref);

Expand Down
19 changes: 4 additions & 15 deletions src/CLR/CorLib/corlib_native_System_Convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,30 +523,19 @@ HRESULT Library_corlib_native_System_Convert::NativeToDateTime___STATIC__SystemD
{
NANOCLR_HEADER();

CLR_RT_TypeDescriptor dtType;
CLR_INT64 *pRes;
uint64_t ticks;
CLR_INT64 *value;

char *str = (char *)stack.Arg0().RecoverString();
char *conversionResult = NULL;
// char *str = (char *)"1999-10-31 10:00:00Z";
uint64_t ticks;

// grab parameter with flag to throw on failure
bool throwOnFailure = (bool)stack.Arg1().NumericByRefConst().u1;

CLR_RT_HeapBlock &ref = stack.PushValue();

// check string parameter for null
FAULT_ON_NULL_ARG(str);

// initialize <DateTime> type descriptor
NANOCLR_CHECK_HRESULT(dtType.InitializeFromType(g_CLR_RT_WellKnownTypes.m_DateTime));

// create an instance of <DateTime>
NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObject(ref, dtType.m_handlerCls));

pRes = Library_corlib_native_System_DateTime::GetValuePtr(ref);

// try 'u' Universal time with sortable format (yyyy-MM-dd' 'HH:mm:ss)
conversionResult = Nano_strptime(str, "%Y-%m-%d %H:%M:%SZ", &ticks);
if (conversionResult == NULL)
Expand All @@ -570,12 +559,12 @@ HRESULT Library_corlib_native_System_Convert::NativeToDateTime___STATIC__SystemD
if (conversionResult == NULL)
{
// failed to parse string

NANOCLR_SET_AND_LEAVE(CLR_E_FORMAT_EXCEPTION);
}
else
{
*pRes = ticks;
value = Library_corlib_native_System_DateTime::NewObject(stack);
*value = ticks;
}

NANOCLR_CLEANUP();
Expand Down
60 changes: 27 additions & 33 deletions src/CLR/CorLib/corlib_native_System_DateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,54 +151,49 @@ HRESULT Library_corlib_native_System_DateTime::get_UtcNow___STATIC__SystemDateTi
{
NATIVE_PROFILE_CLR_CORE();
NANOCLR_HEADER();

CLR_RT_TypeDescriptor dtType;
CLR_INT64* val;

CLR_RT_HeapBlock& ref = stack.PushValue();

// initialize <DateTime> type descriptor
NANOCLR_CHECK_HRESULT( dtType.InitializeFromType(g_CLR_RT_WellKnownTypes.m_DateTime));

// create an instance of <DateTime>
NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObject(ref, dtType.m_handlerCls));
CLR_INT64 *val = NewObject(stack);

val = GetValuePtr(ref);

// load with full date&time
// including UTC flag
*val = HAL_Time_CurrentDateTime(false) | s_UTCMask;
*val = (CLR_INT64)(HAL_Time_CurrentDateTime(false) | s_UTCMask);

NANOCLR_NOCLEANUP();
NANOCLR_NOCLEANUP_NOLABEL();
}

HRESULT Library_corlib_native_System_DateTime::get_Today___STATIC__SystemDateTime(CLR_RT_StackFrame &stack)
{
NATIVE_PROFILE_CLR_CORE();
NANOCLR_HEADER();

CLR_INT64 *val = NewObject(stack);

// load with date part only
// including UTC flag
*val = (CLR_INT64)(HAL_Time_CurrentDateTime(true) | s_UTCMask);

NANOCLR_NOCLEANUP_NOLABEL();
}

//--//

CLR_INT64 *Library_corlib_native_System_DateTime::NewObject(CLR_RT_StackFrame &stack)
{
NATIVE_PROFILE_CLR_CORE();

CLR_RT_TypeDescriptor dtType;
CLR_INT64* val;

CLR_RT_HeapBlock& ref = stack.PushValue();
CLR_RT_HeapBlock &ref = stack.PushValue();

// initialize <DateTime> type descriptor
NANOCLR_CHECK_HRESULT(dtType.InitializeFromType(g_CLR_RT_WellKnownTypes.m_DateTime));
dtType.InitializeFromType(g_CLR_RT_WellKnownTypes.m_DateTime);

// create an instance of <DateTime>
NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObject( ref, dtType.m_handlerCls));
g_CLR_RT_ExecutionEngine.NewObject(ref, dtType.m_handlerCls);

val = GetValuePtr( ref );

// load with date part only
// including UTC flag
*val = HAL_Time_CurrentDateTime(true) | s_UTCMask;

NANOCLR_NOCLEANUP();
return GetValuePtr(ref);
}

//--//

CLR_INT64 *Library_corlib_native_System_DateTime::GetValuePtr(CLR_RT_StackFrame &stack)
{
NATIVE_PROFILE_CLR_CORE();
Expand All @@ -221,17 +216,16 @@ CLR_INT64 *Library_corlib_native_System_DateTime::GetValuePtr(CLR_RT_HeapBlock &

// after dereferencing the object if it's pointing to another Object
// need to do it again because this DateTime instance is most likely boxed
if (dt == DATATYPE_OBJECT)
if (dt == DATATYPE_OBJECT || dt == DATATYPE_BYREF)
{
obj = obj->Dereference();

if (!obj)
{
return NULL;
dt = obj->DataType();
}
}

if (dt == DATATYPE_DATETIME)
{
return (CLR_INT64 *)&obj->NumericByRef().s8;
dt = obj->DataType();
}

if (dt == DATATYPE_I8)
Expand Down
12 changes: 1 addition & 11 deletions src/CLR/CorLib/corlib_native_System_Reflection_FieldInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,7 @@ HRESULT Library_corlib_native_System_Reflection_FieldInfo::SetValue___VOID__OBJE
#endif
}

switch(obj->DataType())
{
case DATATYPE_DATETIME: // Special case.
case DATATYPE_TIMESPAN: // Special case.
obj->NumericByRef().s8 = val.NumericByRefConst().s8;
break;

default:
obj->Assign( val );
break;
}
obj->Assign(val);

NANOCLR_NOCLEANUP();
}
Expand Down
17 changes: 9 additions & 8 deletions src/CLR/CorLib/corlib_native_System_TimeSpan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,18 @@ HRESULT Library_corlib_native_System_TimeSpan::Equals___STATIC__BOOLEAN__SystemT
CLR_INT64 *Library_corlib_native_System_TimeSpan::NewObject(CLR_RT_StackFrame &stack)
{
NATIVE_PROFILE_CLR_CORE();

CLR_RT_TypeDescriptor dtType;

CLR_RT_HeapBlock &ref = stack.PushValue();

ref.SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_TIMESPAN, 0, 1));
ref.ClearData();
// initialize <TimeSpan> type descriptor
dtType.InitializeFromType(g_CLR_RT_WellKnownTypes.m_TimeSpan);

return (CLR_INT64 *)&ref.NumericByRef().s8;
// create an instance of <TimeSpan>
g_CLR_RT_ExecutionEngine.NewObject(ref, dtType.m_handlerCls);

return GetValuePtr(ref);
}

CLR_INT64 *Library_corlib_native_System_TimeSpan::GetValuePtr(CLR_RT_StackFrame &stack)
Expand All @@ -209,11 +215,6 @@ CLR_INT64 *Library_corlib_native_System_TimeSpan::GetValuePtr(CLR_RT_HeapBlock &
dt = obj->DataType();
}

if (dt == DATATYPE_TIMESPAN)
{
return (CLR_INT64 *)&obj->NumericByRef().s8;
}

if (dt == DATATYPE_I8)
{
return (CLR_INT64 *)&obj->NumericByRef().s8;
Expand Down
46 changes: 5 additions & 41 deletions src/CLR/Core/CLR_RT_HeapBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ HRESULT CLR_RT_HeapBlock::EnsureObjectReference(CLR_RT_HeapBlock *&obj)
{
case DATATYPE_CLASS:
case DATATYPE_VALUETYPE:
case DATATYPE_DATETIME: // Special case.
case DATATYPE_TIMESPAN: // Special case.
NANOCLR_SET_AND_LEAVE(S_OK);

default:
Expand All @@ -191,11 +189,6 @@ HRESULT CLR_RT_HeapBlock::EnsureObjectReference(CLR_RT_HeapBlock *&obj)
}
break;

case DATATYPE_DATETIME: // Special case.
case DATATYPE_TIMESPAN: // Special case.
obj = this;
NANOCLR_SET_AND_LEAVE(S_OK);

default:
// the remaining data types aren't to be handled
break;
Expand Down Expand Up @@ -358,24 +351,11 @@ void CLR_RT_HeapBlock::FixArrayReferenceForValueTypes()
NATIVE_PROFILE_CLR_CORE();
CLR_RT_HeapBlock_Array *array = m_data.arrayReference.array;

//
// ValueTypes are implemented as pointers to objects,
// so getting an array reference to a ValueType has to be treated like assigning a pointer!
//
// DateTime and TimeSpan are optimized as primitive types,
// so getting an array reference to them is like getting a reference to them.
//
switch (array->m_typeOfElement)
if (array->m_typeOfElement == DATATYPE_VALUETYPE)
{
case DATATYPE_VALUETYPE:
this->SetReference(*(CLR_RT_HeapBlock *)array->GetElement(m_data.arrayReference.index));
break;

case DATATYPE_DATETIME:
case DATATYPE_TIMESPAN:
m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_BYREF, 0, 1);
m_data.objectReference.ptr = (CLR_RT_HeapBlock *)array->GetElement(m_data.arrayReference.index);
break;
this->SetReference(*(CLR_RT_HeapBlock *)array->GetElement(m_data.arrayReference.index));
}
}

Expand Down Expand Up @@ -831,18 +811,6 @@ HRESULT CLR_RT_HeapBlock::PerformBoxing(const CLR_RT_TypeDef_Instance &cls)
g_CLR_RT_ExecutionEngine.ExtractHeapBlocksForClassOrValueTypes(DATATYPE_VALUETYPE, HB_Boxed, cls, 2);
FAULT_ON_NULL(ptr);

switch (dataType)
{
case DATATYPE_DATETIME: // Special case.
case DATATYPE_TIMESPAN: // Special case.
dataType = DATATYPE_I8;
break;

default:
// the remaining data types aren't to be handled
break;
}

ptr[1].SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(dataType, 0, 1));
ptr[1].AssignData(*this);

Expand Down Expand Up @@ -1208,11 +1176,9 @@ CLR_UINT32 CLR_RT_HeapBlock::GetAtomicDataUsedBytes() const
return 4;
break;

case DATATYPE_I8: // Fall through, hashDataSize = 8
case DATATYPE_U8: // Fall through, hashDataSize = 8
case DATATYPE_R8: // Fall through, hashDataSize = 8
case DATATYPE_DATETIME: // Fall through, hashDataSize = 8
case DATATYPE_TIMESPAN:
case DATATYPE_I8: // Fall through, hashDataSize = 8
case DATATYPE_U8: // Fall through, hashDataSize = 8
case DATATYPE_R8: // Fall through, hashDataSize = 8
return 8;
break;

Expand Down Expand Up @@ -1720,8 +1686,6 @@ CLR_INT32 CLR_RT_HeapBlock::Compare_Values(const CLR_RT_HeapBlock &left, const C

case DATATYPE_I8:
case DATATYPE_U8:
case DATATYPE_DATETIME:
case DATATYPE_TIMESPAN:
return CompareValues_Numeric(left, right, fSigned, c_CLR_RT_DataTypeLookup[leftDataType].m_sizeInBytes);

default:
Expand Down
18 changes: 1 addition & 17 deletions src/CLR/Core/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2513,10 +2513,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
case DATATYPE_VALUETYPE:
evalPos[0].Assign(obj[fieldInst.CrossReference().m_offset]);
goto Execute_LoadAndPromote;
case DATATYPE_DATETIME:
case DATATYPE_TIMESPAN:
evalPos[0].SetInteger((CLR_INT64)obj->NumericByRefConst().s8);
break;

#if defined(NANOCLR_APPDOMAINS)
case DATATYPE_TRANSPARENT_PROXY:
{
Expand Down Expand Up @@ -2564,10 +2561,6 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
{
evalPos[0].SetReference(obj[fieldInst.CrossReference().m_offset]);
}
else if (dt == DATATYPE_DATETIME || dt == DATATYPE_TIMESPAN) // Special case.
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); // NOT SUPPORTED.
}
else
{
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
Expand Down Expand Up @@ -2600,10 +2593,6 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
case DATATYPE_VALUETYPE:
obj[fieldInst.CrossReference().m_offset].AssignAndPreserveType(evalPos[2]);
break;
case DATATYPE_DATETIME: // Special case.
case DATATYPE_TIMESPAN: // Special case.
obj->NumericByRef().s8 = evalPos[2].NumericByRefConst().s8;
break;

#if defined(NANOCLR_APPDOMAINS)
case DATATYPE_TRANSPARENT_PROXY:
Expand Down Expand Up @@ -3484,17 +3473,12 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
break;
case DATATYPE_R4:
break;

case DATATYPE_I8:
break;
case DATATYPE_U8:
break;
case DATATYPE_R8:
break;
case DATATYPE_DATETIME:
break;
case DATATYPE_TIMESPAN:
break;
case DATATYPE_STRING:
break;

Expand Down
12 changes: 9 additions & 3 deletions src/CLR/Core/NativeEventDispatcher/NativeEventDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "stdafx.h"
#include <nanoCLR_Hardware.h>
#include <nf_rt_events_native.h>
#include <corlib_native.h>

////////////////////////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -223,11 +224,13 @@ HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::StartDispatch(

NANOCLR_HEADER();

CLR_INT64 *value;

CLR_RT_StackFrame *stackTop;
CLR_RT_HeapBlock *args;
CLR_RT_HeapBlock_Delegate *dlg;
CLR_RT_HeapBlock *event;
const CLR_UINT64 c_UTCMask = 0x8000000000000000ULL;
const CLR_UINT64 c_UTCMask = ULONGLONGCONSTANT(0x8000000000000000);

InterruptPortInterrupt &interrupt = appInterrupt->m_interruptPortInterrupt;

Expand All @@ -252,8 +255,11 @@ HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::StartDispatch(
//
args[0].SetInteger(interrupt.data1);
args[1].SetInteger(interrupt.data2);
args[2].SetInteger((CLR_UINT64)interrupt.time | c_UTCMask);
args[2].ChangeDataType(DATATYPE_DATETIME);

value = Library_corlib_native_System_DateTime::GetValuePtr(args[2]);
FAULT_ON_NULL(value);

*value = (CLR_UINT64)interrupt.time | c_UTCMask;

th->m_terminationCallback = CLR_RT_HeapBlock_NativeEventDispatcher::ThreadTerminationCallback;
th->m_terminationParameter = appInterrupt;
Expand Down
Loading

0 comments on commit 4b07c76

Please sign in to comment.