@@ -203,6 +203,31 @@ static uindex_t s_context_slot_count;
203203
204204// //////////////////////////////////////////////////////////////////////////////
205205
206+ static MCStringRef __MCScriptDefinitionKindToString (MCScriptDefinitionKind p_kind)
207+ {
208+ switch (p_kind)
209+ {
210+ case kMCScriptDefinitionKindNone : return MCSTR (" unknown" );
211+ case kMCScriptDefinitionKindExternal : return MCSTR (" external" );
212+ case kMCScriptDefinitionKindType : return MCSTR (" type" );
213+ case kMCScriptDefinitionKindConstant : return MCSTR (" constant" );
214+ case kMCScriptDefinitionKindVariable : return MCSTR (" variable" );
215+ case kMCScriptDefinitionKindHandler : return MCSTR (" handler" );
216+ case kMCScriptDefinitionKindForeignHandler : return MCSTR (" handler" );
217+ case kMCScriptDefinitionKindProperty : return MCSTR (" property" );
218+ case kMCScriptDefinitionKindEvent : return MCSTR (" event" );
219+ case kMCScriptDefinitionKindSyntax : return MCSTR (" syntax" );
220+ case kMCScriptDefinitionKindDefinitionGroup : return MCSTR (" group" );
221+ case kMCScriptDefinitionKindContextVariable : return MCSTR (" context variable" );
222+ default :
223+ return MCSTR (" unknown" );
224+ }
225+
226+ return kMCEmptyString ;
227+ }
228+
229+ // //////////////////////////////////////////////////////////////////////////////
230+
206231void MCScriptDestroyModule (MCScriptModuleRef self)
207232{
208233 __MCScriptValidateObjectAndKind__ (self, kMCScriptObjectKindModule );
@@ -268,7 +293,7 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
268293 if (t_index == UINDEX_MAX)
269294 {
270295 if (!MCMemoryResizeArray (s_context_slot_count + 1 , s_context_slot_owners, s_context_slot_count))
271- return false ;
296+ return false ; // oom
272297
273298 t_index = s_context_slot_count - 1 ;
274299 }
@@ -301,7 +326,7 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
301326 case kMCScriptBytecodeOpJump :
302327 // jump <offset>
303328 if (t_arity != 1 )
304- return false ;
329+ goto invalid_bytecode_error ;
305330
306331 // check resolved address is within handler
307332 break ;
@@ -310,23 +335,23 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
310335 // jumpiftrue <register>, <offset>
311336 // jumpiffalse <register>, <offset>
312337 if (t_arity != 2 )
313- return false ;
338+ goto invalid_bytecode_error ;
314339
315340 // check resolved address is within handler
316341 t_temporary_count = MCMax (t_temporary_count, t_operands[0 ] + 1 );
317342 break ;
318343 case kMCScriptBytecodeOpAssignConstant :
319344 // assignconst <dst>, <index>
320345 if (t_arity != 2 )
321- return false ;
346+ goto invalid_bytecode_error ;
322347
323348 // check index argument is within value pool range
324349 t_temporary_count = MCMax (t_temporary_count, t_operands[0 ] + 1 );
325350 break ;
326351 case kMCScriptBytecodeOpAssign :
327352 // assign <dst>, <src>
328353 if (t_arity != 2 )
329- return false ;
354+ goto invalid_bytecode_error ;
330355
331356 t_temporary_count = MCMax (t_temporary_count, t_operands[0 ] + 1 );
332357 t_temporary_count = MCMax (t_temporary_count, t_operands[1 ] + 1 );
@@ -335,15 +360,15 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
335360 // return
336361 // return <value>
337362 if (t_arity != 0 && t_arity != 1 )
338- return false ;
363+ goto invalid_bytecode_error ;
339364
340365 if (t_arity == 1 )
341366 t_temporary_count = MCMax (t_temporary_count, t_operands[0 ] + 1 );
342367 break ;
343368 case kMCScriptBytecodeOpInvoke :
344369 // invoke <index>, <result>, [ <arg_1>, ..., <arg_n> ]
345370 if (t_arity < 2 )
346- return false ;
371+ goto invalid_bytecode_error ;
347372
348373 // check index operand is within definition range
349374 // check definition[index] is handler or definition group
@@ -354,7 +379,7 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
354379 case kMCScriptBytecodeOpInvokeIndirect :
355380 // invoke *<src>, <result>, [ <arg_1>, ..., <arg_n> ]
356381 if (t_arity < 2 )
357- return false ;
382+ goto invalid_bytecode_error ;
358383
359384 for (uindex_t i = 0 ; i < t_arity; i++)
360385 t_temporary_count = MCMax (t_temporary_count, t_operands[i] + 1 );
@@ -364,7 +389,7 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
364389 // fetch <dst>, <index>
365390 // store <src>, <index>
366391 if (t_arity != 2 )
367- return false ;
392+ goto invalid_bytecode_error ;
368393
369394 // check definition[index] is variable or handler
370395 // check level is appropriate.
@@ -373,7 +398,7 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
373398 case kMCScriptBytecodeOpAssignList :
374399 // assignlist <dst>, [ <elem_1>, ..., <elem_n> ]
375400 if (t_arity < 1 )
376- return false ;
401+ goto invalid_bytecode_error ;
377402
378403 for (uindex_t i = 0 ; i < t_arity; i++)
379404 t_temporary_count = MCMax (t_temporary_count, t_operands[i] + 1 );
@@ -385,7 +410,7 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
385410
386411 // If we didn't reach the limit, the bytecode is malformed.
387412 if (t_bytecode != t_bytecode_limit)
388- return false ;
413+ goto invalid_bytecode_error ;
389414
390415 // The total number of slots we need is params (inc result) + temps.
391416 MCTypeInfoRef t_signature;
@@ -396,6 +421,11 @@ bool MCScriptValidateModule(MCScriptModuleRef self)
396421 // If the module has context
397422
398423 return true ;
424+
425+ invalid_bytecode_error:
426+ return MCErrorThrowGenericWithMessage (MCSTR (" %{name} is not valid - malformed bytecode" ),
427+ " name" , self -> name,
428+ nil);
399429}
400430
401431// //////////////////////////////////////////////////////////////////////////////
@@ -508,19 +538,32 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
508538 /* If the module is already marked as being checked for usability,
509539 * then there must be a cyclic module dependency. */
510540 if (self -> is_in_usable_check)
511- return false ;
541+ return MCErrorThrowGeneric (MCSTR (" cyclic module dependency" ));
542+
512543 self -> is_in_usable_check = true ;
513544
514545 // First ensure we can resolve all its external dependencies.
515546 for (uindex_t i = 0 ; i < self -> dependency_count; i++)
516547 {
517548 MCScriptModuleRef t_module;
518549 if (!MCScriptLookupModule (self -> dependencies[i] . name, t_module))
550+ {
551+ MCErrorThrowGenericWithMessage (MCSTR (" %{name} not usable - dependent module not found %{dependency}" ),
552+ " name" , self -> name,
553+ " dependency" , self -> dependencies[i] . name,
554+ nil);
519555 goto error_cleanup;
556+ }
520557
521558 // A used module must not be a widget.
522559 if (t_module -> module_kind == kMCScriptModuleKindWidget )
560+ {
561+ MCErrorThrowGenericWithMessage (MCSTR (" %{name} not usable - depends on widget module %{dependency}" ),
562+ " name" , self -> name,
563+ " dependency" , self -> dependencies[i] . name,
564+ nil);
523565 goto error_cleanup;
566+ }
524567
525568 // A used module must be usable - do this before resolving imports so
526569 // chained imports work.
@@ -537,7 +580,14 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
537580
538581 MCScriptDefinition *t_def;
539582 if (!MCScriptLookupDefinitionInModule (t_module, t_import_def -> name, t_def))
583+ {
584+ MCErrorThrowGenericWithMessage (MCSTR (" %{name} not usable - %{dependency}.%{definition} not found" ),
585+ " name" , self -> name,
586+ " dependency" , self -> dependencies[i] . name,
587+ " definition" , t_import_def -> name,
588+ nil);
540589 goto error_cleanup;
590+ }
541591
542592 MCScriptModuleRef t_mod;
543593 if (t_def -> kind == kMCScriptDefinitionKindExternal )
@@ -554,7 +604,16 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
554604 {
555605 if (t_import_def -> kind != kMCScriptDefinitionKindHandler ||
556606 t_def -> kind != kMCScriptDefinitionKindForeignHandler )
557- goto error_cleanup;
607+ {
608+ MCErrorThrowGenericWithMessage (MCSTR (" %{name} not usable - %{dependency}.%{definition} expected to be %{expected}, but is %{actual}" ),
609+ " name" , self -> name,
610+ " dependency" , self -> dependencies[i] . name,
611+ " definition" , t_import_def -> name,
612+ " expected" , __MCScriptDefinitionKindToString (t_import_def -> kind),
613+ " actual" , __MCScriptDefinitionKindToString (t_def -> kind),
614+ nil);
615+ goto error_cleanup;
616+ }
558617 }
559618
560619 // Check that signatures match.
@@ -563,7 +622,7 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
563622 t_import_def -> resolved_module = t_mod;
564623 }
565624
566- // Now create the instance we need.
625+ // Now create the instance we need - if this fails its due to out of memory .
567626 if (!MCScriptCreateInstanceOfModule (t_module, self -> dependencies[i] . instance))
568627 goto error_cleanup;
569628 }
@@ -599,11 +658,12 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
599658 {
600659 MCAutoStringRef t_name_string;
601660 if (!MCStringFormat (&t_name_string, " %@.%@" , self -> name, t_public_name))
602- goto error_cleanup;
661+ goto error_cleanup; // oom
603662
604663 MCNewAutoNameRef t_name;
605664 if (!MCNameCreate (*t_name_string, &t_name))
606- goto error_cleanup;
665+ goto error_cleanup; // oom
666+
607667 // If the target type is an alias, named type or optional type then
608668 // we just create an alias. Otherwise it must be a record, foreign,
609669 // handler type - this means it must be named.
@@ -614,21 +674,21 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
614674 MCTypeInfoIsOptional (t_target_type))
615675 {
616676 if (!MCAliasTypeInfoCreate (*t_name, t_target_type, &t_typeinfo))
617- goto error_cleanup;
677+ goto error_cleanup; // oom
618678 }
619679 else
620680 {
621681 if (!MCNamedTypeInfoCreate (*t_name, &t_typeinfo))
622- goto error_cleanup;
682+ goto error_cleanup; // oom
623683
624684 if (!MCNamedTypeInfoBind (*t_typeinfo, t_target_type))
625- goto error_cleanup;
685+ goto error_cleanup; // oom
626686 }
627687 }
628688 else
629689 {
630690 if (!MCAliasTypeInfoCreate (kMCEmptyName , self -> types[t_type_def -> type] -> typeinfo, &t_typeinfo))
631- goto error_cleanup;
691+ goto error_cleanup; // oom
632692 }
633693 }
634694 else if (t_def -> kind == kMCScriptDefinitionKindExternal )
@@ -652,7 +712,7 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
652712 MCScriptOptionalType *t_type;
653713 t_type = static_cast <MCScriptOptionalType *>(self -> types[i]);
654714 if (!MCOptionalTypeInfoCreate (self -> types[t_type -> type] -> typeinfo, &t_typeinfo))
655- goto error_cleanup;
715+ goto error_cleanup; // oom
656716 }
657717 break ;
658718 case kMCScriptTypeKindForeign :
@@ -668,7 +728,9 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
668728#endif
669729 if (t_symbol == nil)
670730 {
671- MCLog (" Unable to resolve foreign type '%@'" , t_type -> binding);
731+ MCErrorThrowGenericWithMessage (MCSTR (" %{name} not usable - unable to resolve foreign type '%{type}'" ),
732+ " type" , t_type -> binding,
733+ nil);
672734 goto error_cleanup;
673735 }
674736
@@ -687,11 +749,11 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
687749 t_field . name = t_type -> fields[i] . name;
688750 t_field . type = self -> types[t_type -> fields[i] . type] -> typeinfo;
689751 if (!t_fields . Push (t_field))
690- goto error_cleanup;
752+ goto error_cleanup; // oom
691753 }
692754
693755 if (!MCRecordTypeInfoCreate (t_fields . Ptr (), t_type -> field_count, self -> types[t_type -> base_type] -> typeinfo, &t_typeinfo))
694- goto error_cleanup;
756+ goto error_cleanup; // oom
695757 }
696758 break ;
697759 case kMCScriptTypeKindHandler :
@@ -710,7 +772,7 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
710772 }
711773
712774 if (!MCHandlerTypeInfoCreate (t_parameters . Ptr (), t_type -> parameter_count, self -> types[t_type -> return_type] -> typeinfo, &t_typeinfo))
713- goto error_cleanup;
775+ goto error_cleanup; // oom
714776 }
715777 break ;
716778 }
0 commit comments