Skip to content

Commit bcd919b

Browse files
committed
[[ NilAsUnassigned ]] Make the nil pointer mean unassigned
This patch changes the VM to make the nil pointer mean that a slot is currently unassigned. This allows there to be a distinction between kMCNull (nothing) and slots which have no value.
1 parent da702f2 commit bcd919b

File tree

3 files changed

+60
-89
lines changed

3 files changed

+60
-89
lines changed

libscript/src/script-instance.cpp

Lines changed: 53 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,6 @@ bool MCScriptCreateInstanceOfModule(MCScriptModuleRef p_module, MCScriptInstance
160160

161161
t_instance->slots[t_slot_index] = MCValueRetain(t_default);
162162
}
163-
164-
/* Fill in all remaining slots with null values */
165-
for(uindex_t i = 0; i < p_module -> slot_count; i++)
166-
{
167-
if (nil == t_instance->slots[i])
168-
{
169-
t_instance -> slots[i] = MCValueRetain(kMCNull);
170-
}
171-
}
172163

173164
// If this is a module which shares its instance, then add a link to it.
174165
// (Note this is weak reference - we don't retain, otherwise we would have
@@ -550,8 +541,7 @@ MCScriptCheckedFetchFromVariableInInstance(MCScriptInstanceRef self,
550541
MCValueRef t_value;
551542
t_value = self -> slots[p_definition -> slot_index];
552543

553-
if (t_value == kMCNull &&
554-
!MCTypeInfoIsOptional(self -> module -> types[p_definition -> type] -> typeinfo))
544+
if (t_value == nil)
555545
return MCScriptThrowGlobalVariableUsedBeforeDefinedError(self -> module,
556546
p_definition);
557547

@@ -874,9 +864,6 @@ static bool MCScriptCreateFrame(MCScriptFrame *p_caller, MCScriptInstanceRef p_i
874864
return false;
875865
}
876866

877-
for(uindex_t i = 0; i < p_handler -> slot_count; i++)
878-
self -> slots[i] = MCValueRetain(kMCNull);
879-
880867
self -> caller = p_caller;
881868
self -> instance = MCScriptRetainInstance(p_instance);
882869
self -> handler = p_handler;
@@ -901,23 +888,21 @@ MCScriptFrameInitializeParametersCaller(MCScriptFrame *self,
901888
{
902889
MCHandlerTypeFieldMode t_mode =
903890
MCHandlerTypeInfoGetParameterMode(t_signature, i);
904-
905-
MCValueRef t_value;
906-
if (t_mode != kMCHandlerTypeFieldModeOut)
907-
{
908-
t_value = self->caller->slots[p_arguments[i]];
909-
}
910-
else
911-
{
912-
t_value = kMCNull;
913-
}
914-
891+
892+
if (t_mode != kMCHandlerTypeFieldModeIn)
893+
{
894+
t_needs_mapping = true;
895+
}
896+
897+
if (t_mode == kMCHandlerTypeFieldModeOut)
898+
{
899+
continue;
900+
}
901+
902+
MCValueRef t_value;
903+
t_value = self->caller->slots[p_arguments[i]];
904+
915905
MCValueAssign(self->slots[i], t_value);
916-
917-
if (t_mode != kMCHandlerTypeFieldModeIn)
918-
{
919-
t_needs_mapping = true;
920-
}
921906
}
922907

923908
if (t_needs_mapping)
@@ -946,15 +931,11 @@ MCScriptFrameInitializeParametersImmediate(MCScriptFrame *self,
946931
MCHandlerTypeFieldMode t_mode =
947932
MCHandlerTypeInfoGetParameterMode(t_signature, i);
948933

934+
if (t_mode == kMCHandlerTypeFieldModeOut)
935+
continue;
936+
949937
MCValueRef t_value;
950-
if (t_mode != kMCHandlerTypeFieldModeOut)
951-
{
952-
t_value = p_arguments[i];
953-
}
954-
else
955-
{
956-
t_value = kMCNull;
957-
}
938+
t_value = p_arguments[i];
958939

959940
MCValueAssign(self->slots[i], t_value);
960941
}
@@ -984,7 +965,7 @@ MCScriptFrameInitializeSlots(MCScriptFrame *self)
984965

985966
if (nil == t_default)
986967
{
987-
t_default = kMCNull;
968+
continue;
988969
}
989970

990971
MCValueAssign(self->slots[i], t_default);
@@ -1069,24 +1050,6 @@ static inline MCTypeInfoRef MCScriptGetRegisterTypeInFrame(MCScriptFrame *p_fram
10691050
return nil;
10701051
}
10711052

1072-
static bool MCScriptGetRegisterTypeIsOptionalInFrame(MCScriptFrame *p_frame, uindex_t p_register)
1073-
{
1074-
/* LOAD CHECK */ __MCScriptAssert__(MCScriptIsRegisterValidInFrame(p_frame, p_register),
1075-
"register out of range on fetch register type is optional");
1076-
1077-
MCTypeInfoRef t_type;
1078-
t_type = MCScriptGetRegisterTypeInFrame(p_frame, p_register);
1079-
1080-
if (t_type == nil)
1081-
return true;
1082-
1083-
MCResolvedTypeInfo t_resolved_type;
1084-
if (!MCTypeInfoResolve(t_type, t_resolved_type))
1085-
return true; /* RESOLVE UNCHECKED */
1086-
1087-
return t_resolved_type . is_optional;
1088-
}
1089-
10901053
static inline MCValueRef MCScriptFetchFromRegisterInFrame(MCScriptFrame *p_frame, uindex_t p_register)
10911054
{
10921055
/* LOAD CHECK */ __MCScriptAssert__(MCScriptIsRegisterValidInFrame(p_frame, p_register),
@@ -1124,8 +1087,7 @@ static bool MCScriptCheckedFetchFromRegisterInFrame(MCScriptFrame *p_frame, uind
11241087
MCValueRef t_value;
11251088
t_value = MCScriptFetchFromRegisterInFrame(p_frame, p_register);
11261089

1127-
if (t_value == kMCNull &&
1128-
!MCScriptGetRegisterTypeIsOptionalInFrame(p_frame, p_register))
1090+
if (t_value == nil)
11291091
return MCScriptThrowLocalVariableUsedBeforeDefinedError(p_frame -> instance -> module, p_frame -> handler, p_register);
11301092

11311093
r_value = t_value;
@@ -2017,7 +1979,8 @@ static bool MCScriptPerformMultiInvoke(MCScriptFrame*& x_frame, byte_t*& x_next_
20171979
continue;
20181980

20191981
MCValueRef t_value;
2020-
t_value = MCScriptFetchFromRegisterInFrame(x_frame, p_arguments[j + 1]);
1982+
if (!MCScriptCheckedFetchFromRegisterInFrame(x_frame, p_arguments[j + 1], t_value))
1983+
return false;
20211984

20221985
MCTypeInfoRef t_value_type, t_param_type;
20231986
t_value_type = MCValueGetTypeInfo(t_value);
@@ -2160,20 +2123,23 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
21602123

21612124
// if the value in the register is true, then jump.
21622125
MCValueRef t_value;
2163-
t_value = MCScriptFetchFromRegisterInFrame(t_frame, t_register);
2126+
t_success = MCScriptCheckedFetchFromRegisterInFrame(t_frame, t_register, t_value);
21642127

2165-
if (MCValueGetTypeCode(t_value) == kMCValueTypeCodeBoolean)
2166-
{
2167-
if (t_value == kMCTrue)
2168-
t_next_bytecode = t_bytecode + t_offset;
2169-
}
2170-
else if (MCValueGetTypeInfo(t_value) == kMCBoolTypeInfo)
2128+
if (t_success)
21712129
{
2172-
if (*(bool *)MCForeignValueGetContentsPtr(t_value) == 0)
2173-
t_next_bytecode = t_bytecode + t_offset;
2130+
if (MCValueGetTypeCode(t_value) == kMCValueTypeCodeBoolean)
2131+
{
2132+
if (t_value == kMCTrue)
2133+
t_next_bytecode = t_bytecode + t_offset;
2134+
}
2135+
else if (MCValueGetTypeInfo(t_value) == kMCBoolTypeInfo)
2136+
{
2137+
if (*(bool *)MCForeignValueGetContentsPtr(t_value) == 0)
2138+
t_next_bytecode = t_bytecode + t_offset;
2139+
}
2140+
else
2141+
t_success = MCScriptThrowNotABooleanError(t_value);
21742142
}
2175-
else
2176-
t_success = MCScriptThrowNotABooleanError(t_value);
21772143
}
21782144
break;
21792145
case kMCScriptBytecodeOpJumpIfFalse:
@@ -2185,20 +2151,23 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
21852151

21862152
// if the value in the register is true, then jump.
21872153
MCValueRef t_value;
2188-
t_value = MCScriptFetchFromRegisterInFrame(t_frame, t_register);
2154+
t_success = MCScriptCheckedFetchFromRegisterInFrame(t_frame, t_register, t_value);
21892155

2190-
if (MCValueGetTypeCode(t_value) == kMCValueTypeCodeBoolean)
2191-
{
2192-
if (t_value == kMCFalse)
2193-
t_next_bytecode = t_bytecode + t_offset;
2194-
}
2195-
else if (MCValueGetTypeInfo(t_value) == kMCBoolTypeInfo)
2156+
if (t_success)
21962157
{
2197-
if (*(bool *)MCForeignValueGetContentsPtr(t_value) == 0)
2198-
t_next_bytecode = t_bytecode + t_offset;
2158+
if (MCValueGetTypeCode(t_value) == kMCValueTypeCodeBoolean)
2159+
{
2160+
if (t_value == kMCFalse)
2161+
t_next_bytecode = t_bytecode + t_offset;
2162+
}
2163+
else if (MCValueGetTypeInfo(t_value) == kMCBoolTypeInfo)
2164+
{
2165+
if (*(bool *)MCForeignValueGetContentsPtr(t_value) == 0)
2166+
t_next_bytecode = t_bytecode + t_offset;
2167+
}
2168+
else
2169+
t_success = MCScriptThrowNotABooleanError(t_value);
21992170
}
2200-
else
2201-
t_success = MCScriptThrowNotABooleanError(t_value);
22022171
}
22032172
break;
22042173
case kMCScriptBytecodeOpAssignConstant:
@@ -2273,10 +2242,9 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
22732242

22742243
// Check that all out variables which should be defined are.
22752244
for(uindex_t i = 0; t_success && i < MCHandlerTypeInfoGetParameterCount(t_signature); i++)
2276-
if (MCHandlerTypeInfoGetParameterMode(t_signature, i) == kMCHandlerTypeFieldModeOut)
2245+
if (MCHandlerTypeInfoGetParameterMode(t_signature, i) != kMCHandlerTypeFieldModeIn)
22772246
{
2278-
if (MCScriptFetchFromRegisterInFrame(t_frame, i) == kMCNull &&
2279-
!MCScriptGetRegisterTypeIsOptionalInFrame(t_frame, i))
2247+
if (MCScriptFetchFromRegisterInFrame(t_frame, i) == nil)
22802248
t_success = MCScriptThrowOutParameterNotDefinedError(t_frame -> instance -> module, t_frame -> handler, i);
22812249
}
22822250

libscript/src/script-module.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,10 @@ MCNameRef MCScriptGetNameOfLocalVariableInModule(MCScriptModuleRef self, MCScrip
10981098
if (p_index < t_type -> parameter_name_count)
10991099
return t_type -> parameter_names[p_index];
11001100

1101-
return t_handler -> local_names[p_index - t_type -> parameter_name_count];
1101+
if (p_index - t_type -> parameter_name_count < t_handler -> local_name_count)
1102+
return t_handler -> local_names[p_index - t_type -> parameter_name_count];
1103+
1104+
return kMCEmptyName;
11021105
}
11031106

11041107
////////////////////////////////////////////////////////////////////////////////

libscript/src/script-object.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,11 @@ bool MCScriptInitialize(void)
243243

244244
// This block creates all the default errors
245245
{
246-
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.InParameterNotDefinedError"), MCNAME("runtime"), MCSTR("In parameters must be defined before calling - parameter %{parameter} of %{module}.%{handler}"), kMCScriptInParameterNotDefinedErrorTypeInfo))
246+
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.InParameterNotDefinedError"), MCNAME("runtime"), MCSTR("In parameters must be assigned before calling - parameter %{parameter} of %{module}.%{handler}"), kMCScriptInParameterNotDefinedErrorTypeInfo))
247247
return false;
248-
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.OutParameterNotDefinedError"), MCNAME("runtime"), MCSTR("Out parameters must be defined before returning - parameter %{parameter} of %{module}.%{handler}"), kMCScriptOutParameterNotDefinedErrorTypeInfo))
248+
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.OutParameterNotDefinedError"), MCNAME("runtime"), MCSTR("Out parameters must be assigned before returning - parameter %{parameter} of %{module}.%{handler}"), kMCScriptOutParameterNotDefinedErrorTypeInfo))
249249
return false;
250-
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.VariableUsedBeforeDefinedError"), MCNAME("runtime"), MCSTR("Variables must be defined before being used - variable %{variable} in %{module}.%{handler}"), kMCScriptVariableUsedBeforeDefinedErrorTypeInfo))
250+
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.VariableUsedBeforeDefinedError"), MCNAME("runtime"), MCSTR("Variables must be assigned before being used - variable %{variable} in %{module}.%{handler}"), kMCScriptVariableUsedBeforeDefinedErrorTypeInfo))
251251
return false;
252252
if (!MCNamedErrorTypeInfoCreate(MCNAME("livecode.lang.ReturnValueTypeError"), MCNAME("runtime"), MCSTR("Value is not of correct type for return - expected type %{type} when returning from %{module}.%{handler}"), kMCScriptInvalidReturnValueErrorTypeInfo))
253253
return false;

0 commit comments

Comments
 (0)