@@ -218,6 +218,11 @@ bool MCScriptThrowInvalidValueForGlobalVariableError(MCScriptModuleRef p_module,
218218 return MCErrorCreateAndThrow (kMCScriptInvalidVariableValueErrorTypeInfo , " module" , p_module -> name, " variable" , MCScriptGetNameOfGlobalVariableInModule (p_module, p_index), " type" , MCNamedTypeInfoGetName (p_expected_type), " value" , p_value, nil);
219219}
220220
221+ bool MCScriptThrowInvalidValueForContextVariableError (MCScriptModuleRef p_module, uindex_t p_index, MCTypeInfoRef p_expected_type, MCValueRef p_value)
222+ {
223+ return MCErrorCreateAndThrow (kMCScriptInvalidVariableValueErrorTypeInfo , " module" , p_module -> name, " variable" , MCScriptGetNameOfContextVariableInModule (p_module, p_index), " type" , MCNamedTypeInfoGetName (p_expected_type), " value" , p_value, nil);
224+ }
225+
221226bool MCScriptThrowNotABooleanError (MCValueRef p_value)
222227{
223228 return MCErrorCreateAndThrow (kMCScriptNotABooleanValueErrorTypeInfo , " value" , p_value, nil);
@@ -522,6 +527,12 @@ bool MCScriptCallHandlerOfInstanceIfFound(MCScriptInstanceRef self, MCNameRef p_
522527
523528// //////////////////////////////////////////////////////////////////////////////
524529
530+ struct MCScriptFrameContext
531+ {
532+ uindex_t count;
533+ MCValueRef slots[1 ];
534+ };
535+
525536// This structure is a single frame on the execution stack.
526537struct MCScriptFrame
527538{
@@ -542,6 +553,9 @@ struct MCScriptFrame
542553 // <locals>
543554 // <registers>
544555 MCValueRef *slots;
556+
557+ // The context slots for the current handler invocation (if initialized)
558+ MCScriptFrameContext *context;
545559
546560 // The result register in the caller.
547561 uindex_t result;
@@ -2151,7 +2165,23 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
21512165
21522166 if (t_success)
21532167 t_success = MCScriptCheckedStoreToRegisterInFrame (t_frame, t_dst, t_value);
2168+ }
2169+ else if (t_definition -> kind == kMCScriptDefinitionKindContextVariable )
2170+ {
2171+ MCScriptContextVariableDefinition *t_var_definition;
2172+ t_var_definition = static_cast <MCScriptContextVariableDefinition *>(t_definition);
21542173
2174+ // If there is no context table, or the value of the slot at the given
2175+ // index is nil then we use the default.
2176+ MCValueRef t_value;
2177+ if (t_frame -> context == nil ||
2178+ t_frame -> context -> count < t_var_definition -> slot_index ||
2179+ t_frame -> context -> slots[t_var_definition -> slot_index] == nil)
2180+ t_value = kMCFalse ; // t_instance -> module -> values[t_var_definition -> default_value];
2181+ else
2182+ t_value = t_frame -> context -> slots[t_var_definition -> slot_index];
2183+
2184+ t_success = MCScriptCheckedStoreToRegisterInFrame (t_frame, t_dst, t_value);
21552185 }
21562186 else if (t_definition -> kind == kMCScriptDefinitionKindHandler )
21572187 {
@@ -2231,30 +2261,53 @@ bool MCScriptCallHandlerOfInstanceInternal(MCScriptInstanceRef self, MCScriptHan
22312261 MCScriptDefinition *t_definition;
22322262 MCScriptResolveDefinitionInFrame (t_frame, t_index, t_instance, t_definition);
22332263
2234- __MCScriptAssert__ (t_definition -> kind == kMCScriptDefinitionKindVariable ,
2235- " definition not a variable in store global" );
2236-
2237- MCScriptVariableDefinition *t_var_definition;
2238- t_var_definition = static_cast <MCScriptVariableDefinition *>(t_definition);
2239-
2240- MCTypeInfoRef t_output_type;
2241- t_output_type = t_instance -> module -> types[t_var_definition -> type] -> typeinfo;
2242-
22432264 MCValueRef t_value;
22442265 t_success = MCScriptCheckedFetchFromRegisterInFrame (t_frame, t_dst, t_value);
22452266
2246- if (t_success &&
2247- !MCTypeInfoConforms (MCValueGetTypeInfo (t_value), t_output_type))
2248- t_success = MCScriptThrowInvalidValueForGlobalVariableError (t_frame -> instance -> module , t_index, t_output_type, t_value);
2249-
2250- if (t_success)
2267+ if (t_definition -> kind == kMCScriptDefinitionKindVariable )
2268+ {
2269+ MCScriptVariableDefinition *t_var_definition;
2270+ t_var_definition = static_cast <MCScriptVariableDefinition *>(t_definition);
2271+
2272+ MCTypeInfoRef t_output_type;
2273+ t_output_type = t_instance -> module -> types[t_var_definition -> type] -> typeinfo;
2274+
2275+ if (t_success &&
2276+ !MCTypeInfoConforms (MCValueGetTypeInfo (t_value), t_output_type))
2277+ t_success = MCScriptThrowInvalidValueForGlobalVariableError (t_frame -> instance -> module , t_index, t_output_type, t_value);
2278+
2279+ if (t_success)
2280+ MCValueAssign (t_instance -> slots[t_var_definition -> slot_index], t_value);
2281+ }
2282+ else if (t_definition -> kind == kMCScriptDefinitionKindContextVariable )
22512283 {
2252- if (t_instance -> slots[t_var_definition -> slot_index] != t_value)
2284+ MCScriptContextVariableDefinition *t_var_definition;
2285+ t_var_definition = static_cast <MCScriptContextVariableDefinition *>(t_definition);
2286+
2287+ MCTypeInfoRef t_output_type;
2288+ t_output_type = t_instance -> module -> types[t_var_definition -> type] -> typeinfo;
2289+
2290+ if (t_success &&
2291+ !MCTypeInfoConforms (MCValueGetTypeInfo (t_value), t_output_type))
2292+ t_success = MCScriptThrowInvalidValueForContextVariableError (t_frame -> instance -> module , t_index, t_output_type, t_value);
2293+
2294+ if (t_success &&
2295+ (t_frame -> context == nil ||
2296+ t_frame -> context -> count <= t_var_definition -> slot_index))
22532297 {
2254- MCValueRelease (t_instance -> slots[t_var_definition -> slot_index]);
2255- t_instance -> slots[t_var_definition -> slot_index] = MCValueRetain (t_value);
2298+ // Note that MCScriptFrameContext has an implement MCValueRef
2299+ // so we don't need to adjust index to be a count.
2300+ if (MCMemoryReallocate (t_frame -> context, sizeof (MCScriptFrameContext) + (sizeof (MCValueRef) * t_var_definition -> slot_index), t_frame -> context))
2301+ t_frame -> context -> count = t_var_definition -> slot_index + 1 ;
2302+ else
2303+ t_success = false ;
22562304 }
2305+
2306+ if (t_success)
2307+ MCValueAssign (t_frame -> context -> slots[t_var_definition -> slot_index], t_value);
22572308 }
2309+ else
2310+ MCUnreachable ();
22582311 }
22592312 break ;
22602313 case kMCScriptBytecodeOpAssignList :
0 commit comments