1 //**************************************************************************
2 //**
3 //**	##   ##    ##    ##   ##   ####     ####   ###     ###
4 //**	##   ##  ##  ##  ##   ##  ##  ##   ##  ##  ####   ####
5 //**	 ## ##  ##    ##  ## ##  ##    ## ##    ## ## ## ## ##
6 //**	 ## ##  ########  ## ##  ##    ## ##    ## ##  ###  ##
7 //**	  ###   ##    ##   ###    ##  ##   ##  ##  ##       ##
8 //**	   #    ##    ##    #      ####     ####   ##       ##
9 //**
10 //**	$Id: vc_expr_invoke.cpp 4327 2010-07-24 19:30:53Z firebrand_kh $
11 //**
12 //**	Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //**	This program is free software; you can redistribute it and/or
15 //**  modify it under the terms of the GNU General Public License
16 //**  as published by the Free Software Foundation; either version 2
17 //**  of the License, or (at your option) any later version.
18 //**
19 //**	This program is distributed in the hope that it will be useful,
20 //**  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //**  GNU General Public License for more details.
23 //**
24 //**************************************************************************
25 
26 // HEADER FILES ------------------------------------------------------------
27 
28 #include "vc_local.h"
29 
30 // MACROS ------------------------------------------------------------------
31 
32 // TYPES -------------------------------------------------------------------
33 
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35 
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37 
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39 
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41 
42 // PUBLIC DATA DEFINITIONS -------------------------------------------------
43 
44 // PRIVATE DATA DEFINITIONS ------------------------------------------------
45 
46 // CODE --------------------------------------------------------------------
47 
48 //==========================================================================
49 //
50 //	VBaseInvocation::VBaseInvocation
51 //
52 //==========================================================================
53 
VBaseInvocation(VName AName,int ANumArgs,VExpression ** AArgs,const TLocation & ALoc)54 VBaseInvocation::VBaseInvocation(VName AName, int ANumArgs, VExpression** AArgs,
55 	const TLocation& ALoc)
56 : VExpression(ALoc)
57 , Name(AName)
58 , NumArgs(ANumArgs)
59 {
60 	guard(VBaseInvocation::VBaseInvocation);
61 	for (int i = 0; i < NumArgs; i++)
62 	{
63 		Args[i] = AArgs[i];
64 	}
65 	unguard;
66 }
67 
68 //==========================================================================
69 //
70 //	VBaseInvocation::~VBaseInvocation
71 //
72 //==========================================================================
73 
~VBaseInvocation()74 VBaseInvocation::~VBaseInvocation()
75 {
76 	guard(VBaseInvocation::~VBaseInvocation);
77 	for (int i = 0; i < NumArgs; i++)
78 	{
79 		delete Args[i];
80 		Args[i] = NULL;
81 	}
82 	unguard;
83 }
84 
85 //==========================================================================
86 //
87 //	VBaseInvocation::DoResolve
88 //
89 //==========================================================================
90 
DoResolve(VEmitContext & ec)91 VExpression* VBaseInvocation::DoResolve(VEmitContext& ec)
92 {
93 	guard(VBaseInvocation::DoResolve);
94 	if (!ec.SelfClass)
95 	{
96 		ParseError(Loc, ":: not in method");
97 		delete this;
98 		return NULL;
99 	}
100 	VMethod* Func = ec.SelfClass->ParentClass->FindMethod(Name);
101 	if (!Func)
102 	{
103 		ParseError(Loc, "No such method %s", *Name);
104 		delete this;
105 		return NULL;
106 	}
107 
108 	VExpression* e = new VInvocation(NULL, Func, NULL, false,
109 		true, Loc, NumArgs, Args);
110 	NumArgs = 0;
111 	delete this;
112 	return e->Resolve(ec);
113 	unguard;
114 }
115 
116 //==========================================================================
117 //
118 //	VBaseInvocation::Emit
119 //
120 //==========================================================================
121 
Emit(VEmitContext &)122 void VBaseInvocation::Emit(VEmitContext&)
123 {
124 	guard(VBaseInvocation::Emit);
125 	ParseError(Loc, "Should not happen");
126 	unguard;
127 }
128 
129 //==========================================================================
130 //
131 //	VCastOrInvocation::VCastOrInvocation
132 //
133 //==========================================================================
134 
VCastOrInvocation(VName AName,const TLocation & ALoc,int ANumArgs,VExpression ** AArgs)135 VCastOrInvocation::VCastOrInvocation(VName AName, const TLocation& ALoc, int ANumArgs,
136 	VExpression** AArgs)
137 : VExpression(ALoc)
138 , Name(AName)
139 , NumArgs(ANumArgs)
140 {
141 	for (int i = 0; i < NumArgs; i++)
142 		Args[i] = AArgs[i];
143 }
144 
145 //==========================================================================
146 //
147 //	VCastOrInvocation::~VCastOrInvocation
148 //
149 //==========================================================================
150 
~VCastOrInvocation()151 VCastOrInvocation::~VCastOrInvocation()
152 {
153 	for (int i = 0; i < NumArgs; i++)
154 	{
155 		if (Args[i])
156 		{
157 			delete Args[i];
158 			Args[i] = NULL;
159 		}
160 	}
161 }
162 
163 //==========================================================================
164 //
165 //	VCastOrInvocation::DoResolve
166 //
167 //==========================================================================
168 
DoResolve(VEmitContext & ec)169 VExpression* VCastOrInvocation::DoResolve(VEmitContext& ec)
170 {
171 	VClass* Class = VMemberBase::StaticFindClass(Name);
172 	if (Class)
173 	{
174 		if (NumArgs != 1 || !Args[0])
175 		{
176 			ParseError(Loc, "Dynamic cast requires 1 argument");
177 			delete this;
178 			return NULL;
179 		}
180 		VExpression* e = new VDynamicCast(Class, Args[0], Loc);
181 		NumArgs = 0;
182 		delete this;
183 		return e->Resolve(ec);
184 	}
185 
186 	if (ec.SelfClass)
187 	{
188 		VMethod* M = ec.SelfClass->FindMethod(Name);
189 		if (M)
190 		{
191 			if (M->Flags & FUNC_Iterator)
192 			{
193 				ParseError(Loc, "Iterator methods can only be used in foreach statements");
194 				delete this;
195 				return NULL;
196 			}
197 			VExpression* e = new VInvocation(NULL, M, NULL,
198 				false, false, Loc, NumArgs, Args);
199 			NumArgs = 0;
200 			delete this;
201 			return e->Resolve(ec);
202 		}
203 		VField* field = ec.SelfClass->FindField(Name, Loc, ec.SelfClass);
204 		if (field && field->Type.Type == TYPE_Delegate)
205 		{
206 			VExpression* e = new VInvocation(NULL, field->Func, field,
207 				false, false, Loc, NumArgs, Args);
208 			NumArgs = 0;
209 			delete this;
210 			return e->Resolve(ec);
211 		}
212 	}
213 
214 	ParseError(Loc, "Unknown method %s", *Name);
215 	delete this;
216 	return NULL;
217 }
218 
219 //==========================================================================
220 //
221 //	VCastOrInvocation::ResolveIterator
222 //
223 //==========================================================================
224 
ResolveIterator(VEmitContext & ec)225 VExpression* VCastOrInvocation::ResolveIterator(VEmitContext& ec)
226 {
227 	VMethod* M = ec.SelfClass->FindMethod(Name);
228 	if (!M)
229 	{
230 		ParseError(Loc, "Unknown method %s", *Name);
231 		delete this;
232 		return NULL;
233 	}
234 	if (!(M->Flags & FUNC_Iterator))
235 	{
236 		ParseError(Loc, "%s is not an iterator method", *Name);
237 		delete this;
238 		return NULL;
239 	}
240 
241 	VExpression* e = new VInvocation(NULL, M, NULL, false, false, Loc,
242 		NumArgs, Args);
243 	NumArgs = 0;
244 	delete this;
245 	return e->Resolve(ec);
246 }
247 
248 //==========================================================================
249 //
250 //	VCastOrInvocation::Emit
251 //
252 //==========================================================================
253 
Emit(VEmitContext &)254 void VCastOrInvocation::Emit(VEmitContext&)
255 {
256 	ParseError(Loc, "Should not happen");
257 }
258 
259 //==========================================================================
260 //
261 //	VDotInvocation::VDotInvocation
262 //
263 //==========================================================================
264 
VDotInvocation(VExpression * ASelfExpr,VName AMethodName,const TLocation & ALoc,int ANumArgs,VExpression ** AArgs)265 VDotInvocation::VDotInvocation(VExpression* ASelfExpr, VName AMethodName,
266 	const TLocation& ALoc, int ANumArgs, VExpression** AArgs)
267 : VExpression(ALoc)
268 , SelfExpr(ASelfExpr)
269 , MethodName(AMethodName)
270 , NumArgs(ANumArgs)
271 {
272 	for (int i = 0; i < NumArgs; i++)
273 		Args[i] = AArgs[i];
274 }
275 
276 //==========================================================================
277 //
278 //	VDotInvocation::~VDotInvocation
279 //
280 //==========================================================================
281 
~VDotInvocation()282 VDotInvocation::~VDotInvocation()
283 {
284 	if (SelfExpr)
285 	{
286 		delete SelfExpr;
287 		SelfExpr = NULL;
288 	}
289 	for (int i = 0; i < NumArgs; i++)
290 	{
291 		delete Args[i];
292 		Args[i] = NULL;
293 	}
294 }
295 
296 //==========================================================================
297 //
298 //	VDotInvocation::DoResolve
299 //
300 //==========================================================================
301 
DoResolve(VEmitContext & ec)302 VExpression* VDotInvocation::DoResolve(VEmitContext& ec)
303 {
304 	if (SelfExpr)
305 		SelfExpr = SelfExpr->Resolve(ec);
306 	if (!SelfExpr)
307 	{
308 		delete this;
309 		return NULL;
310 	}
311 
312 	if (SelfExpr->Type.Type == TYPE_DynamicArray)
313 	{
314 		if (MethodName == NAME_Insert)
315 		{
316 			if (NumArgs == 1)
317 			{
318 				//	Default count is 1
319 				Args[1] = new VIntLiteral(1, Loc);
320 				NumArgs = 2;
321 			}
322 			if (NumArgs != 2)
323 			{
324 				ParseError(Loc, "Insert requires 1 or 2 arguments");
325 				delete this;
326 				return NULL;
327 			}
328 			VExpression* e = new VDynArrayInsert(SelfExpr, Args[0], Args[1], Loc);
329 			SelfExpr = NULL;
330 			NumArgs = 0;
331 			delete this;
332 			return e->Resolve(ec);
333 		}
334 
335 		if (MethodName == NAME_Remove)
336 		{
337 			if (NumArgs == 1)
338 			{
339 				//	Default count is 1
340 				Args[1] = new VIntLiteral(1, Loc);
341 				NumArgs = 2;
342 			}
343 			if (NumArgs != 2)
344 			{
345 				ParseError(Loc, "Insert requires 1 or 2 arguments");
346 				delete this;
347 				return NULL;
348 			}
349 			VExpression* e = new VDynArrayRemove(SelfExpr, Args[0], Args[1], Loc);
350 			SelfExpr = NULL;
351 			NumArgs = 0;
352 			delete this;
353 			return e->Resolve(ec);
354 		}
355 
356 		ParseError(Loc, "Invalid operation on dynamic array");
357 		delete this;
358 		return NULL;
359 	}
360 
361 	if (SelfExpr->Type.Type != TYPE_Reference)
362 	{
363 		ParseError(Loc, "Object reference expected left side of .");
364 		delete this;
365 		return NULL;
366 	}
367 
368 	VMethod* M = SelfExpr->Type.Class->FindMethod(MethodName);
369 	if (M)
370 	{
371 		if (M->Flags & FUNC_Iterator)
372 		{
373 			ParseError(Loc, "Iterator methods can only be used in foreach statements");
374 			delete this;
375 			return NULL;
376 		}
377 		VExpression* e = new VInvocation(SelfExpr, M, NULL, true,
378 			false, Loc, NumArgs, Args);
379 		SelfExpr = NULL;
380 		NumArgs = 0;
381 		delete this;
382 		return e->Resolve(ec);
383 	}
384 
385 	VField* field = SelfExpr->Type.Class->FindField(MethodName, Loc,
386 		ec.SelfClass);
387 	if (field && field->Type.Type == TYPE_Delegate)
388 	{
389 		VExpression* e = new VInvocation(SelfExpr, field->Func, field, true,
390 			false, Loc, NumArgs, Args);
391 		SelfExpr = NULL;
392 		NumArgs = 0;
393 		delete this;
394 		return e->Resolve(ec);
395 	}
396 
397 	ParseError(Loc, "No such method %s", *MethodName);
398 	delete this;
399 	return NULL;
400 }
401 
402 //==========================================================================
403 //
404 //	VDotInvocation::ResolveIterator
405 //
406 //==========================================================================
407 
ResolveIterator(VEmitContext & ec)408 VExpression* VDotInvocation::ResolveIterator(VEmitContext& ec)
409 {
410 	if (SelfExpr)
411 		SelfExpr = SelfExpr->Resolve(ec);
412 	if (!SelfExpr)
413 	{
414 		delete this;
415 		return NULL;
416 	}
417 
418 	if (SelfExpr->Type.Type != TYPE_Reference)
419 	{
420 		ParseError(Loc, "Object reference expected left side of .");
421 		delete this;
422 		return NULL;
423 	}
424 
425 	VMethod* M = SelfExpr->Type.Class->FindMethod(MethodName);
426 	if (!M)
427 	{
428 		ParseError(Loc, "No such method %s", *MethodName);
429 		delete this;
430 		return NULL;
431 	}
432 	if (!(M->Flags & FUNC_Iterator))
433 	{
434 		ParseError(Loc, "%s is not an iterator method", *MethodName);
435 		delete this;
436 		return NULL;
437 	}
438 
439 	VExpression* e = new VInvocation(SelfExpr, M, NULL, true,
440 		false, Loc, NumArgs, Args);
441 	SelfExpr = NULL;
442 	NumArgs = 0;
443 	delete this;
444 	return e->Resolve(ec);
445 }
446 
447 //==========================================================================
448 //
449 //	VDotInvocation::Emit
450 //
451 //==========================================================================
452 
Emit(VEmitContext &)453 void VDotInvocation::Emit(VEmitContext&)
454 {
455 	ParseError(Loc, "Should not happen");
456 }
457 
458 //==========================================================================
459 //
460 //	VInvocation::VInvocation
461 //
462 //==========================================================================
463 
VInvocation(VExpression * ASelfExpr,VMethod * AFunc,VField * ADelegateField,bool AHaveSelf,bool ABaseCall,const TLocation & ALoc,int ANumArgs,VExpression ** AArgs)464 VInvocation::VInvocation(VExpression* ASelfExpr, VMethod* AFunc, VField* ADelegateField,
465 	bool AHaveSelf, bool ABaseCall, const TLocation& ALoc, int ANumArgs,
466 	VExpression** AArgs)
467 : VExpression(ALoc)
468 , SelfExpr(ASelfExpr)
469 , Func(AFunc)
470 , DelegateField(ADelegateField)
471 , HaveSelf(AHaveSelf)
472 , BaseCall(ABaseCall)
473 , NumArgs(ANumArgs)
474 , CallerState(NULL)
475 , MultiFrameState(false)
476 {
477 	guard(VInvocation::VInvocation);
478 	for (int i = 0; i < NumArgs; i++)
479 	{
480 		Args[i] = AArgs[i];
481 	}
482 	unguard;
483 }
484 
485 //==========================================================================
486 //
487 //	VInvocation::~VInvocation
488 //
489 //==========================================================================
490 
~VInvocation()491 VInvocation::~VInvocation()
492 {
493 	guard(VInvocation::~VInvocation);
494 	if (SelfExpr)
495 	{
496 		delete SelfExpr;
497 		SelfExpr = NULL;
498 	}
499 	for (int i = 0; i < NumArgs; i++)
500 	{
501 		delete Args[i];
502 		Args[i] = NULL;
503 	}
504 	unguard;
505 }
506 
507 //==========================================================================
508 //
509 //	VInvocation::DoResolve
510 //
511 //==========================================================================
512 
DoResolve(VEmitContext & ec)513 VExpression* VInvocation::DoResolve(VEmitContext& ec)
514 {
515 	guard(VInvocation::DoResolve);
516 	if (ec.Package->Name == NAME_decorate)
517 	{
518 		CheckDecorateParams(ec);
519 	}
520 
521 	//	Resolve arguments
522 	bool ArgsOk = true;
523 	for (int i = 0; i < NumArgs; i++)
524 	{
525 		if (Args[i])
526 		{
527 			Args[i] = Args[i]->Resolve(ec);
528 			if (!Args[i])
529 			{
530 				ArgsOk = false;
531 			}
532 		}
533 	}
534 	if (!ArgsOk)
535 	{
536 		delete this;
537 		return NULL;
538 	}
539 
540 	CheckParams(ec);
541 
542 	Type  = Func->ReturnType;
543 	if (Type.Type == TYPE_Byte || Type.Type == TYPE_Bool)
544 		Type = VFieldType(TYPE_Int);
545 	if (Func->Flags & FUNC_Spawner)
546 		Type.Class = Args[0]->Type.Class;
547 	return this;
548 	unguard;
549 }
550 
551 //==========================================================================
552 //
553 //	VInvocation::Emit
554 //
555 //==========================================================================
556 
Emit(VEmitContext & ec)557 void VInvocation::Emit(VEmitContext& ec)
558 {
559 	guard(VInvocation::Emit);
560 	if (SelfExpr)
561 	{
562 		SelfExpr->Emit(ec);
563 	}
564 
565 	bool DirectCall = BaseCall || (Func->Flags & FUNC_Final);
566 
567 	if (Func->Flags & FUNC_Static)
568 	{
569 		if (HaveSelf)
570 		{
571 			ParseError(Loc, "Invalid static function call");
572 		}
573 	}
574 	else
575 	{
576 		if (!HaveSelf)
577 		{
578 			if (ec.CurrentFunc->Flags & FUNC_Static)
579 			{
580 				ParseError(Loc, "An object is required to call non-static methods");
581 			}
582 			ec.AddStatement(OPC_LocalValue0);
583 		}
584 	}
585 
586 	vint32 SelfOffset = 1;
587 	for (int i = 0; i < NumArgs; i++)
588 	{
589 		if (!Args[i])
590 		{
591 			switch (Func->ParamTypes[i].Type)
592 			{
593 			case TYPE_Int:
594 			case TYPE_Byte:
595 			case TYPE_Bool:
596 			case TYPE_Float:
597 			case TYPE_Name:
598 				ec.EmitPushNumber(0);
599 				SelfOffset++;
600 				break;
601 
602 			case TYPE_String:
603 			case TYPE_Pointer:
604 			case TYPE_Reference:
605 			case TYPE_Class:
606 			case TYPE_State:
607 				ec.AddStatement(OPC_PushNull);
608 				SelfOffset++;
609 				break;
610 
611 			case TYPE_Vector:
612 				ec.EmitPushNumber(0);
613 				ec.EmitPushNumber(0);
614 				ec.EmitPushNumber(0);
615 				SelfOffset += 3;
616 				break;
617 
618 			default:
619 				ParseError(Loc, "Bad optional parameter type");
620 				break;
621 			}
622 			ec.EmitPushNumber(0);
623 			SelfOffset++;
624 		}
625 		else
626 		{
627 			Args[i]->Emit(ec);
628 			if (Args[i]->Type.Type == TYPE_Vector)
629 				SelfOffset += 3;
630 			else
631 				SelfOffset++;
632 			if (Func->ParamFlags[i] & FPARM_Optional)
633 			{
634 				ec.EmitPushNumber(1);
635 				SelfOffset++;
636 			}
637 		}
638 	}
639 
640 	if (DirectCall)
641 	{
642 		ec.AddStatement(OPC_Call, Func);
643 	}
644 	else if (DelegateField)
645 	{
646 		ec.AddStatement(OPC_DelegateCall, DelegateField, SelfOffset);
647 	}
648 	else
649 	{
650 		ec.AddStatement(OPC_VCall, Func, SelfOffset);
651 	}
652 	unguard;
653 }
654 
655 //==========================================================================
656 //
657 //	VInvocation::CheckParams
658 //
659 //==========================================================================
660 
CheckParams(VEmitContext & ec)661 void VInvocation::CheckParams(VEmitContext& ec)
662 {
663 	guard(VInvocation::CheckParams);
664 	//	Determine parameter count.
665 	int argsize = 0;
666 	int max_params;
667 	int num_needed_params = Func->NumParams;
668 	if (Func->Flags & FUNC_VarArgs)
669 	{
670 		max_params = VMethod::MAX_PARAMS - 1;
671 	}
672 	else
673 	{
674 		max_params = Func->NumParams;
675 	}
676 
677 	for (int i = 0; i < NumArgs; i++)
678 	{
679 		if (i < num_needed_params)
680 		{
681 			if (!Args[i])
682 			{
683 				if (!(Func->ParamFlags[i] & FPARM_Optional))
684 				{
685 					ParseError(Loc, "Bad expresion");
686 				}
687 				argsize += Func->ParamTypes[i].GetStackSize();
688 			}
689 			else
690 			{
691 				if (ec.Package->Name == NAME_decorate)
692 				{
693 					switch (Func->ParamTypes[i].Type)
694 					{
695 					case TYPE_Int:
696 						if (Args[i]->IsFloatConst())
697 						{
698 							int Val = int(Args[i]->GetFloatConst());
699 							TLocation Loc = Args[i]->Loc;
700 							delete Args[i];
701 							Args[i] = NULL;
702 							Args[i] = new VIntLiteral(Val, Loc);
703 							Args[i] = Args[i]->Resolve(ec);
704 						}
705 						else if (Args[i]->Type.Type == TYPE_Float)
706 						{
707 							VExpression* TmpArgs[1];
708 							TmpArgs[0] = Args[i];
709 							Args[i] = new VInvocation(NULL,
710 								ec.SelfClass->FindMethodChecked("ftoi"), NULL,
711 								false, false, Args[i]->Loc, 1, TmpArgs);
712 							Args[i] = Args[i]->Resolve(ec);
713 						}
714 						break;
715 
716 					case TYPE_Float:
717 						if (Args[i]->IsIntConst())
718 						{
719 							int Val = Args[i]->GetIntConst();
720 							TLocation Loc = Args[i]->Loc;
721 							delete Args[i];
722 							Args[i] = NULL;
723 							Args[i] = new VFloatLiteral(Val, Loc);
724 							Args[i] = Args[i]->Resolve(ec);
725 						}
726 						else if (Args[i]->Type.Type == TYPE_Int)
727 						{
728 							VExpression* TmpArgs[1];
729 							TmpArgs[0] = Args[i];
730 							Args[i] = new VInvocation(NULL,
731 								ec.SelfClass->FindMethodChecked("itof"), NULL,
732 								false, false, Args[i]->Loc, 1, TmpArgs);
733 							Args[i] = Args[i]->Resolve(ec);
734 						}
735 						break;
736 					}
737 				}
738 				if (Func->ParamFlags[i] & FPARM_Out)
739 				{
740 					if (!Args[i]->Type.Equals(Func->ParamTypes[i]))
741 					{
742 						//FIXME This should be error.
743 						if (!Func->ParamFlags[NumArgs] & FPARM_Optional)
744 						{
745 							Args[i]->Type.CheckMatch(Args[i]->Loc, Func->ParamTypes[i]);
746 							//ParseError(Args[i]->Loc, "Out parameter types must be equal");
747 						}
748 					}
749 					Args[i]->RequestAddressOf();
750 				}
751 				else
752 				{
753 					if (!Func->ParamFlags[NumArgs] & FPARM_Optional)
754 					{
755 						Args[i]->Type.CheckMatch(Args[i]->Loc, Func->ParamTypes[i]);
756 					}
757 				}
758 				argsize += Args[i]->Type.GetStackSize();
759 			}
760 		}
761 		else if (!Args[i])
762 		{
763 			if (!Args[i]->Type.Equals(Func->ParamTypes[i]))
764 			{
765 				ParseError(Loc, "Bad expresion");
766 			}
767 		}
768 		else
769 		{
770 			argsize += Args[i]->Type.GetStackSize();
771 		}
772 	}
773 	if (NumArgs > max_params)
774 	{
775 		ParseError(Loc, "Incorrect number of arguments, need %d, got %d.", max_params, NumArgs);
776 	}
777 	while (NumArgs < num_needed_params)
778 	{
779 		if (Func->ParamFlags[NumArgs] & FPARM_Optional)
780 		{
781 			Args[NumArgs] = NULL;
782 			NumArgs++;
783 		}
784 		else
785 		{
786 			ParseError(Loc, "Incorrect argument count %d, should be %d",
787 				NumArgs, num_needed_params);
788 			break;
789 		}
790 	}
791 
792 	if (Func->Flags & FUNC_VarArgs)
793 	{
794 		Args[NumArgs++] = new VIntLiteral(argsize / 4 - num_needed_params, Loc);
795 	}
796 	unguard;
797 }
798 
799 //==========================================================================
800 //
801 //	VInvocation::CheckDecorateParams
802 //
803 //==========================================================================
804 
CheckDecorateParams(VEmitContext & ec)805 void VInvocation::CheckDecorateParams(VEmitContext& ec)
806 {
807 	guard(VInvocation::CheckDecorateParams);
808 	int max_params;
809 	int num_needed_params = Func->NumParams;
810 	if (Func->Flags & FUNC_VarArgs)
811 	{
812 		max_params = VMethod::MAX_PARAMS - 1;
813 	}
814 	else
815 	{
816 		max_params = Func->NumParams;
817 	}
818 
819 	for (int i = 0; i < NumArgs; i++)
820 	{
821 		if (i >= num_needed_params)
822 		{
823 			continue;
824 		}
825 		if (!Args[i])
826 		{
827 			continue;
828 		}
829 		switch (Func->ParamTypes[i].Type)
830 		{
831 		case TYPE_Name:
832 			if (Args[i]->IsDecorateSingleName())
833 			{
834 				VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
835 				Args[i] = new VNameLiteral(*E->Name, E->Loc);
836 				delete E;
837 				E = NULL;
838 			}
839 			else if (Args[i]->IsStrConst())
840 			{
841 				VStr Val = Args[i]->GetStrConst(ec.Package);
842 				TLocation ALoc = Args[i]->Loc;
843 				delete Args[i];
844 				Args[i] = NULL;
845 				Args[i] = new VNameLiteral(*Val, ALoc);
846 			}
847 			break;
848 
849 		case TYPE_String:
850 			if (Args[i]->IsDecorateSingleName())
851 			{
852 				VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
853 				Args[i] = new VStringLiteral(ec.Package->FindString(*E->Name), E->Loc);
854 				delete E;
855 				E = NULL;
856 			}
857 			break;
858 
859 		case TYPE_Class:
860 			if (Args[i]->IsDecorateSingleName())
861 			{
862 				VDecorateSingleName* E = (VDecorateSingleName*)Args[i];
863 				Args[i] = new VStringLiteral(ec.Package->FindString(*E->Name), E->Loc);
864 				delete E;
865 				E = NULL;
866 			}
867 			if (Args[i]->IsStrConst())
868 			{
869 				VStr CName = Args[i]->GetStrConst(ec.Package);
870 				TLocation ALoc = Args[i]->Loc;
871 				VClass* Cls = VClass::FindClassNoCase(*CName);
872 				if (!Cls)
873 				{
874 					ParseWarning(ALoc, "No such class %s", *CName);
875 					delete Args[i];
876 					Args[i] = NULL;
877 					Args[i] = new VNoneLiteral(ALoc);
878 				}
879 				else if (Func->ParamTypes[i].Class &&
880 					!Cls->IsChildOf(Func->ParamTypes[i].Class))
881 				{
882 					ParseWarning(ALoc, "Class %s is not a descendant of %s",
883 						*CName, Func->ParamTypes[i].Class->GetName());
884 					delete Args[i];
885 					Args[i] = NULL;
886 					Args[i] = new VNoneLiteral(ALoc);
887 				}
888 				else
889 				{
890 					delete Args[i];
891 					Args[i] = NULL;
892 					Args[i] = new VClassConstant(Cls, ALoc);
893 				}
894 			}
895 			break;
896 
897 		case TYPE_State:
898 			if (Args[i]->IsIntConst())
899 			{
900 				int Offs = Args[i]->GetIntConst();
901 				TLocation ALoc = Args[i]->Loc;
902 				if (Offs < 0)
903 				{
904 					ParseError(ALoc, "Negative state jumps are not allowed");
905 				}
906 				else if (Offs == 0)
907 				{
908 					//	0 means no state
909 					delete Args[i];
910 					Args[i] = NULL;
911 					Args[i] = new VNoneLiteral(ALoc);
912 				}
913 				else
914 				{
915 					check(CallerState);
916 					VState* S = CallerState->GetPlus(Offs, true);
917 					if (!S)
918 					{
919 						ParseError(ALoc, "Bad state jump offset");
920 					}
921 					else
922 					{
923 						delete Args[i];
924 						Args[i] = NULL;
925 						Args[i] = new VStateConstant(S, ALoc);
926 					}
927 				}
928 			}
929 			else if (Args[i]->IsStrConst())
930 			{
931 				VStr Lbl = Args[i]->GetStrConst(ec.Package);
932 				TLocation ALoc = Args[i]->Loc;
933 				int DCol = Lbl.IndexOf("::");
934 				if (DCol >= 0)
935 				{
936 					//	Jump to a specific parent class state, resolve it and
937 					// pass value directly.
938 					VStr ClassName(Lbl, 0, DCol);
939 					VClass* CheckClass;
940 					if (ClassName.ICmp("Super"))
941 					{
942 						CheckClass = ec.SelfClass->ParentClass;
943 					}
944 					else
945 					{
946 						CheckClass = VClass::FindClassNoCase(*ClassName);
947 						if (!CheckClass)
948 						{
949 							ParseError(ALoc, "No such class %s", *ClassName);
950 						}
951 						else if (!ec.SelfClass->IsChildOf(CheckClass))
952 						{
953 							ParseError(ALoc, "%s is not a subclass of %s",
954 								ec.SelfClass->GetName(), CheckClass->GetName());
955 							CheckClass = NULL;
956 						}
957 					}
958 					if (CheckClass)
959 					{
960 						VStr LblName(Lbl, DCol + 2, Lbl.Length() - DCol - 2);
961 						TArray<VName> Names;
962 						VMemberBase::StaticSplitStateLabel(LblName, Names);
963 						VStateLabel* StLbl = CheckClass->FindStateLabel(Names, true);
964 						if (!StLbl)
965 						{
966 							ParseError(ALoc, "No such state %s", *Lbl);
967 						}
968 						else
969 						{
970 							delete Args[i];
971 							Args[i] = NULL;
972 							Args[i] = new VStateConstant(StLbl->State, ALoc);
973 						}
974 					}
975 				}
976 				else
977 				{
978 					//	It's a virtual state jump
979 					VExpression* TmpArgs[1];
980 					TmpArgs[0] = Args[i];
981 					Args[i] = new VInvocation(NULL,
982 						ec.SelfClass->FindMethodChecked("FindJumpState"),
983 						NULL, false, false, Args[i]->Loc, 1, TmpArgs);
984 				}
985 			}
986 			break;
987 		}
988 	}
989 	unguard;
990 }
991