00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "setup.h"
00033
00034 #if OBJECT_SYSTEM
00035
00036 #ifndef _STDIO_INCLUDED_
00037 #include <stdio.h>
00038 #define _STDIO_INCLUDED_
00039 #endif
00040 #include <stdlib.h>
00041
00042 #include "argacces.h"
00043 #include "classcom.h"
00044 #include "classfun.h"
00045 #include "memalloc.h"
00046 #include "constrct.h"
00047 #include "envrnmnt.h"
00048 #include "exprnpsr.h"
00049 #include "insfun.h"
00050 #include "msgcom.h"
00051 #include "msgfun.h"
00052 #include "multifld.h"
00053 #include "prcdrfun.h"
00054 #include "prccode.h"
00055 #include "proflfun.h"
00056 #include "router.h"
00057 #include "strngfun.h"
00058 #include "utility.h"
00059 #include "commline.h"
00060
00061 #define _MSGPASS_SOURCE_
00062 #include "msgpass.h"
00063
00064 #include "inscom.h"
00065
00066
00067
00068
00069
00070
00071
00072 static void PerformMessage(void *,DATA_OBJECT *,EXPRESSION *,SYMBOL_HN *);
00073 static HANDLER_LINK *FindApplicableHandlers(void *,DEFCLASS *,SYMBOL_HN *);
00074 static void CallHandlers(void *,DATA_OBJECT *);
00075 static void EarlySlotBindError(void *,INSTANCE_TYPE *,DEFCLASS *,unsigned);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 globle void DirectMessage(
00097 void *theEnv,
00098 SYMBOL_HN *msg,
00099 INSTANCE_TYPE *ins,
00100 DATA_OBJECT *resultbuf,
00101 EXPRESSION *remargs)
00102 {
00103 EXPRESSION args;
00104 DATA_OBJECT temp;
00105
00106 if (resultbuf == NULL)
00107 resultbuf = &temp;
00108 args.nextArg = remargs;
00109 args.argList = NULL;
00110 args.type = INSTANCE_ADDRESS;
00111 args.value = (void *) ins;
00112 PerformMessage(theEnv,resultbuf,&args,msg);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 globle void EnvSend(
00130 void *theEnv,
00131 DATA_OBJECT *idata,
00132 char *msg,
00133 char *args,
00134 DATA_OBJECT *result)
00135 {
00136 int error;
00137 EXPRESSION *iexp;
00138 SYMBOL_HN *msym;
00139
00140 if ((EvaluationData(theEnv)->CurrentEvaluationDepth == 0) && (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&
00141 (EvaluationData(theEnv)->CurrentExpression == NULL))
00142 { PeriodicCleanup(theEnv,TRUE,FALSE); }
00143
00144 SetEvaluationError(theEnv,FALSE);
00145 result->type = SYMBOL;
00146 result->value = EnvFalseSymbol(theEnv);
00147 msym = FindSymbolHN(theEnv,msg);
00148 if (msym == NULL)
00149 {
00150 PrintNoHandlerError(theEnv,msg);
00151 SetEvaluationError(theEnv,TRUE);
00152 return;
00153 }
00154 iexp = GenConstant(theEnv,idata->type,idata->value);
00155 iexp->nextArg = ParseConstantArguments(theEnv,args,&error);
00156 if (error == TRUE)
00157 {
00158 ReturnExpression(theEnv,iexp);
00159 SetEvaluationError(theEnv,TRUE);
00160 return;
00161 }
00162 PerformMessage(theEnv,result,iexp,msym);
00163 ReturnExpression(theEnv,iexp);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 globle void DestroyHandlerLinks(
00175 void *theEnv,
00176 HANDLER_LINK *mhead)
00177 {
00178 HANDLER_LINK *tmp;
00179
00180 while (mhead != NULL)
00181 {
00182 tmp = mhead;
00183 mhead = mhead->nxt;
00184 tmp->hnd->busy--;
00185 DecrementDefclassBusyCount(theEnv,(void *) tmp->hnd->cls);
00186 rtn_struct(theEnv,messageHandlerLink,tmp);
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 globle void SendCommand(
00201 void *theEnv,
00202 DATA_OBJECT *result)
00203 {
00204 EXPRESSION args;
00205 SYMBOL_HN *msg;
00206 DATA_OBJECT temp;
00207
00208 result->type = SYMBOL;
00209 result->value = EnvFalseSymbol(theEnv);
00210 if (EnvArgTypeCheck(theEnv,"send",2,SYMBOL,&temp) == FALSE)
00211 return;
00212 msg = (SYMBOL_HN *) temp.value;
00213
00214
00215
00216
00217 args.type = GetFirstArgument()->type;
00218 args.value = GetFirstArgument()->value;
00219 args.argList = GetFirstArgument()->argList;
00220 args.nextArg = GetFirstArgument()->nextArg->nextArg;
00221
00222 PerformMessage(theEnv,result,&args,msg);
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 globle DATA_OBJECT *GetNthMessageArgument(
00239 void *theEnv,
00240 int n)
00241 {
00242 return(&ProceduralPrimitiveData(theEnv)->ProcParamArray[n]);
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 globle int NextHandlerAvailable(
00257 void *theEnv)
00258 {
00259 if (MessageHandlerData(theEnv)->CurrentCore == NULL)
00260 return(FALSE);
00261 if (MessageHandlerData(theEnv)->CurrentCore->hnd->type == MAROUND)
00262 return((MessageHandlerData(theEnv)->NextInCore != NULL) ? TRUE : FALSE);
00263 if ((MessageHandlerData(theEnv)->CurrentCore->hnd->type == MPRIMARY) && (MessageHandlerData(theEnv)->NextInCore != NULL))
00264 return((MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY) ? TRUE : FALSE);
00265 return(FALSE);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 globle void CallNextHandler(
00292 void *theEnv,
00293 DATA_OBJECT *result)
00294 {
00295 EXPRESSION args;
00296 int overridep;
00297 HANDLER_LINK *oldNext,*oldCurrent;
00298 #if PROFILING_FUNCTIONS
00299 struct profileFrameInfo profileFrame;
00300 #endif
00301
00302 SetpType(result,SYMBOL);
00303 SetpValue(result,EnvFalseSymbol(theEnv));
00304 EvaluationData(theEnv)->EvaluationError = FALSE;
00305 if (EvaluationData(theEnv)->HaltExecution)
00306 return;
00307 if (NextHandlerAvailable(theEnv) == FALSE)
00308 {
00309 PrintErrorID(theEnv,"MSGPASS",1,FALSE);
00310 EnvPrintRouter(theEnv,WERROR,"Shadowed message-handlers not applicable in current context.\n");
00311 SetEvaluationError(theEnv,TRUE);
00312 return;
00313 }
00314 if (EvaluationData(theEnv)->CurrentExpression->value == (void *) FindFunction(theEnv,"override-next-handler"))
00315 {
00316 overridep = 1;
00317 args.type = ProceduralPrimitiveData(theEnv)->ProcParamArray[0].type;
00318 if (args.type != MULTIFIELD)
00319 args.value = (void *) ProceduralPrimitiveData(theEnv)->ProcParamArray[0].value;
00320 else
00321 args.value = (void *) &ProceduralPrimitiveData(theEnv)->ProcParamArray[0];
00322 args.nextArg = GetFirstArgument();
00323 args.argList = NULL;
00324 PushProcParameters(theEnv,&args,CountArguments(&args),
00325 ValueToString(MessageHandlerData(theEnv)->CurrentMessageName),"message",
00326 UnboundHandlerErr);
00327 if (EvaluationData(theEnv)->EvaluationError)
00328 {
00329 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
00330 return;
00331 }
00332 }
00333 else
00334 overridep = 0;
00335 oldNext = MessageHandlerData(theEnv)->NextInCore;
00336 oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
00337 if (MessageHandlerData(theEnv)->CurrentCore->hnd->type == MAROUND)
00338 {
00339 if (MessageHandlerData(theEnv)->NextInCore->hnd->type == MAROUND)
00340 {
00341 MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
00342 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
00343 #if DEBUGGING_FUNCTIONS
00344 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
00345 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
00346 #endif
00347 if (CheckHandlerArgCount(theEnv))
00348 {
00349 #if PROFILING_FUNCTIONS
00350 StartProfile(theEnv,&profileFrame,
00351 &MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
00352 ProfileFunctionData(theEnv)->ProfileConstructs);
00353 #endif
00354
00355 EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
00356 MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
00357 MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
00358 result,UnboundHandlerErr);
00359 #if PROFILING_FUNCTIONS
00360 EndProfile(theEnv,&profileFrame);
00361 #endif
00362 }
00363 #if DEBUGGING_FUNCTIONS
00364 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
00365 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
00366 #endif
00367 }
00368 else
00369 CallHandlers(theEnv,result);
00370 }
00371 else
00372 {
00373 MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
00374 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
00375 #if DEBUGGING_FUNCTIONS
00376 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
00377 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
00378 #endif
00379 if (CheckHandlerArgCount(theEnv))
00380 {
00381 #if PROFILING_FUNCTIONS
00382 StartProfile(theEnv,&profileFrame,
00383 &MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
00384 ProfileFunctionData(theEnv)->ProfileConstructs);
00385 #endif
00386
00387 EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
00388 MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
00389 MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
00390 result,UnboundHandlerErr);
00391 #if PROFILING_FUNCTIONS
00392 EndProfile(theEnv,&profileFrame);
00393 #endif
00394 }
00395
00396 #if DEBUGGING_FUNCTIONS
00397 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
00398 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
00399 #endif
00400 }
00401 MessageHandlerData(theEnv)->NextInCore = oldNext;
00402 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
00403 if (overridep)
00404 PopProcParameters(theEnv);
00405 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 globle void FindApplicableOfName(
00422 void *theEnv,
00423 DEFCLASS *cls,
00424 HANDLER_LINK *tops[4],
00425 HANDLER_LINK *bots[4],
00426 SYMBOL_HN *mname)
00427 {
00428 register int i;
00429 register int e;
00430 HANDLER *hnd;
00431 unsigned *arr;
00432 HANDLER_LINK *tmp;
00433
00434 i = FindHandlerNameGroup(cls,mname);
00435 if (i == -1)
00436 return;
00437 e = ((int) cls->handlerCount) - 1;
00438 hnd = cls->handlers;
00439 arr = cls->handlerOrderMap;
00440 for ( ; i <= e ; i++)
00441 {
00442 if (hnd[arr[i]].name != mname)
00443 break;
00444
00445 tmp = get_struct(theEnv,messageHandlerLink);
00446 hnd[arr[i]].busy++;
00447 IncrementDefclassBusyCount(theEnv,(void *) hnd[arr[i]].cls);
00448 tmp->hnd = &hnd[arr[i]];
00449 if (tops[tmp->hnd->type] == NULL)
00450 {
00451 tmp->nxt = NULL;
00452 tops[tmp->hnd->type] = bots[tmp->hnd->type] = tmp;
00453 }
00454
00455 else if (tmp->hnd->type == MAFTER)
00456 {
00457 tmp->nxt = tops[tmp->hnd->type];
00458 tops[tmp->hnd->type] = tmp;
00459 }
00460
00461 else
00462 {
00463 bots[tmp->hnd->type]->nxt = tmp;
00464 bots[tmp->hnd->type] = tmp;
00465 tmp->nxt = NULL;
00466 }
00467 }
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 globle HANDLER_LINK *JoinHandlerLinks(
00482 void *theEnv,
00483 HANDLER_LINK *tops[4],
00484 HANDLER_LINK *bots[4],
00485 SYMBOL_HN *mname)
00486 {
00487 register int i;
00488 HANDLER_LINK *mlink;
00489
00490 if (tops[MPRIMARY] == NULL)
00491 {
00492 PrintNoHandlerError(theEnv,ValueToString(mname));
00493 for (i = MAROUND ; i <= MAFTER ; i++)
00494 DestroyHandlerLinks(theEnv,tops[i]);
00495 SetEvaluationError(theEnv,TRUE);
00496 return(NULL);
00497 }
00498
00499 mlink = tops[MPRIMARY];
00500
00501 if (tops[MBEFORE] != NULL)
00502 {
00503 bots[MBEFORE]->nxt = mlink;
00504 mlink = tops[MBEFORE];
00505 }
00506
00507 if (tops[MAROUND] != NULL)
00508 {
00509 bots[MAROUND]->nxt = mlink;
00510 mlink = tops[MAROUND];
00511 }
00512
00513 bots[MPRIMARY]->nxt = tops[MAFTER];
00514
00515 return(mlink);
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 #if WIN_BTC && (! DEVELOPER)
00530 #pragma argsused
00531 #endif
00532 globle void PrintHandlerSlotGetFunction(
00533 void *theEnv,
00534 char *logicalName,
00535 void *theValue)
00536 {
00537 #if DEVELOPER
00538 HANDLER_SLOT_REFERENCE *theReference;
00539 DEFCLASS *theDefclass;
00540 SLOT_DESC *sd;
00541
00542 theReference = (HANDLER_SLOT_REFERENCE *) ValueToBitMap(theValue);
00543 EnvPrintRouter(theEnv,logicalName,"?self:[");
00544 theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
00545 EnvPrintRouter(theEnv,logicalName,ValueToString(theDefclass->header.name));
00546 EnvPrintRouter(theEnv,logicalName,"]");
00547 sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[theReference->slotID] - 1];
00548 EnvPrintRouter(theEnv,logicalName,ValueToString(sd->slotName->name));
00549 #else
00550 #if MAC_MCW || WIN_MCW || MAC_XCD
00551 #pragma unused(theEnv)
00552 #pragma unused(logicalName)
00553 #pragma unused(theValue)
00554 #endif
00555 #endif
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 globle intBool HandlerSlotGetFunction(
00584 void *theEnv,
00585 void *theValue,
00586 DATA_OBJECT *theResult)
00587 {
00588 HANDLER_SLOT_REFERENCE *theReference;
00589 DEFCLASS *theDefclass;
00590 INSTANCE_TYPE *theInstance;
00591 INSTANCE_SLOT *sp;
00592 unsigned instanceSlotIndex;
00593
00594 theReference = (HANDLER_SLOT_REFERENCE *) ValueToBitMap(theValue);
00595 theInstance = (INSTANCE_TYPE *) ProceduralPrimitiveData(theEnv)->ProcParamArray[0].value;
00596 theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
00597
00598 if (theInstance->garbage)
00599 {
00600 StaleInstanceAddress(theEnv,"for slot get",0);
00601 theResult->type = SYMBOL;
00602 theResult->value = EnvFalseSymbol(theEnv);
00603 SetEvaluationError(theEnv,TRUE);
00604 return(FALSE);
00605 }
00606
00607 if (theInstance->cls == theDefclass)
00608 {
00609 instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
00610 sp = theInstance->slotAddresses[instanceSlotIndex - 1];
00611 }
00612 else
00613 {
00614 if (theReference->slotID > theInstance->cls->maxSlotNameID)
00615 goto HandlerGetError;
00616 instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
00617 if (instanceSlotIndex == 0)
00618 goto HandlerGetError;
00619 instanceSlotIndex--;
00620 sp = theInstance->slotAddresses[instanceSlotIndex];
00621 if (sp->desc->cls != theDefclass)
00622 goto HandlerGetError;
00623 }
00624 theResult->type = (unsigned short) sp->type;
00625 theResult->value = sp->value;
00626 if (sp->type == MULTIFIELD)
00627 {
00628 theResult->begin = 0;
00629 SetpDOEnd(theResult,GetInstanceSlotLength(sp));
00630 }
00631 return(TRUE);
00632
00633 HandlerGetError:
00634 EarlySlotBindError(theEnv,theInstance,theDefclass,theReference->slotID);
00635 theResult->type = SYMBOL;
00636 theResult->value = EnvFalseSymbol(theEnv);
00637 SetEvaluationError(theEnv,TRUE);
00638 return(FALSE);
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 #if WIN_BTC && (! DEVELOPER)
00653 #pragma argsused
00654 #endif
00655 globle void PrintHandlerSlotPutFunction(
00656 void *theEnv,
00657 char *logicalName,
00658 void *theValue)
00659 {
00660 #if DEVELOPER
00661 HANDLER_SLOT_REFERENCE *theReference;
00662 DEFCLASS *theDefclass;
00663 SLOT_DESC *sd;
00664
00665 theReference = (HANDLER_SLOT_REFERENCE *) ValueToBitMap(theValue);
00666 EnvPrintRouter(theEnv,logicalName,"(bind ?self:[");
00667 theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
00668 EnvPrintRouter(theEnv,logicalName,ValueToString(theDefclass->header.name));
00669 EnvPrintRouter(theEnv,logicalName,"]");
00670 sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[theReference->slotID] - 1];
00671 EnvPrintRouter(theEnv,logicalName,ValueToString(sd->slotName->name));
00672 if (GetFirstArgument() != NULL)
00673 {
00674 EnvPrintRouter(theEnv,logicalName," ");
00675 PrintExpression(theEnv,logicalName,GetFirstArgument());
00676 }
00677 EnvPrintRouter(theEnv,logicalName,")");
00678 #else
00679 #if MAC_MCW || WIN_MCW || MAC_XCD
00680 #pragma unused(theEnv)
00681 #pragma unused(logicalName)
00682 #pragma unused(theValue)
00683 #endif
00684 #endif
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 globle intBool HandlerSlotPutFunction(
00713 void *theEnv,
00714 void *theValue,
00715 DATA_OBJECT *theResult)
00716 {
00717 HANDLER_SLOT_REFERENCE *theReference;
00718 DEFCLASS *theDefclass;
00719 INSTANCE_TYPE *theInstance;
00720 INSTANCE_SLOT *sp;
00721 unsigned instanceSlotIndex;
00722 DATA_OBJECT theSetVal;
00723
00724 theReference = (HANDLER_SLOT_REFERENCE *) ValueToBitMap(theValue);
00725 theInstance = (INSTANCE_TYPE *) ProceduralPrimitiveData(theEnv)->ProcParamArray[0].value;
00726 theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
00727
00728 if (theInstance->garbage)
00729 {
00730 StaleInstanceAddress(theEnv,"for slot put",0);
00731 theResult->type = SYMBOL;
00732 theResult->value = EnvFalseSymbol(theEnv);
00733 SetEvaluationError(theEnv,TRUE);
00734 return(FALSE);
00735 }
00736
00737 if (theInstance->cls == theDefclass)
00738 {
00739 instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
00740 sp = theInstance->slotAddresses[instanceSlotIndex - 1];
00741 }
00742 else
00743 {
00744 if (theReference->slotID > theInstance->cls->maxSlotNameID)
00745 goto HandlerPutError;
00746 instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
00747 if (instanceSlotIndex == 0)
00748 goto HandlerPutError;
00749 instanceSlotIndex--;
00750 sp = theInstance->slotAddresses[instanceSlotIndex];
00751 if (sp->desc->cls != theDefclass)
00752 goto HandlerPutError;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761 if (sp->desc->initializeOnly && (!theInstance->initializeInProgress))
00762 {
00763 SlotAccessViolationError(theEnv,ValueToString(sp->desc->slotName->name),
00764 TRUE,(void *) theInstance);
00765 goto HandlerPutError2;
00766 }
00767
00768
00769
00770
00771
00772
00773 if (GetFirstArgument())
00774 {
00775 if (EvaluateAndStoreInDataObject(theEnv,(int) sp->desc->multiple,
00776 GetFirstArgument(),&theSetVal,TRUE) == FALSE)
00777 goto HandlerPutError2;
00778 }
00779 else
00780 {
00781 SetDOBegin(theSetVal,1);
00782 SetDOEnd(theSetVal,0);
00783 SetType(theSetVal,MULTIFIELD);
00784 SetValue(theSetVal,ProceduralPrimitiveData(theEnv)->NoParamValue);
00785 }
00786 if (PutSlotValue(theEnv,theInstance,sp,&theSetVal,theResult,NULL) == FALSE)
00787 goto HandlerPutError2;
00788 return(TRUE);
00789
00790 HandlerPutError:
00791 EarlySlotBindError(theEnv,theInstance,theDefclass,theReference->slotID);
00792
00793 HandlerPutError2:
00794 theResult->type = SYMBOL;
00795 theResult->value = EnvFalseSymbol(theEnv);
00796 SetEvaluationError(theEnv,TRUE);
00797
00798 return(FALSE);
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 globle void DynamicHandlerGetSlot(
00811 void *theEnv,
00812 DATA_OBJECT *result)
00813 {
00814 INSTANCE_SLOT *sp;
00815 INSTANCE_TYPE *ins;
00816 DATA_OBJECT temp;
00817
00818 result->type = SYMBOL;
00819 result->value = EnvFalseSymbol(theEnv);
00820 if (CheckCurrentMessage(theEnv,"dynamic-get",TRUE) == FALSE)
00821 return;
00822 EvaluateExpression(theEnv,GetFirstArgument(),&temp);
00823 if (temp.type != SYMBOL)
00824 {
00825 ExpectedTypeError1(theEnv,"dynamic-get",1,"symbol");
00826 SetEvaluationError(theEnv,TRUE);
00827 return;
00828 }
00829 ins = GetActiveInstance(theEnv);
00830 sp = FindInstanceSlot(theEnv,ins,(SYMBOL_HN *) temp.value);
00831 if (sp == NULL)
00832 {
00833 SlotExistError(theEnv,ValueToString(temp.value),"dynamic-get");
00834 return;
00835 }
00836 if ((sp->desc->publicVisibility == 0) &&
00837 (MessageHandlerData(theEnv)->CurrentCore->hnd->cls != sp->desc->cls))
00838 {
00839 SlotVisibilityViolationError(theEnv,sp->desc,MessageHandlerData(theEnv)->CurrentCore->hnd->cls);
00840 SetEvaluationError(theEnv,TRUE);
00841 return;
00842 }
00843 result->type = (unsigned short) sp->type;
00844 result->value = sp->value;
00845 if (sp->type == MULTIFIELD)
00846 {
00847 result->begin = 0;
00848 SetpDOEnd(result,GetInstanceSlotLength(sp));
00849 }
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 globle void DynamicHandlerPutSlot(
00863 void *theEnv,
00864 DATA_OBJECT *theResult)
00865 {
00866 INSTANCE_SLOT *sp;
00867 INSTANCE_TYPE *ins;
00868 DATA_OBJECT temp;
00869
00870 theResult->type = SYMBOL;
00871 theResult->value = EnvFalseSymbol(theEnv);
00872 if (CheckCurrentMessage(theEnv,"dynamic-put",TRUE) == FALSE)
00873 return;
00874 EvaluateExpression(theEnv,GetFirstArgument(),&temp);
00875 if (temp.type != SYMBOL)
00876 {
00877 ExpectedTypeError1(theEnv,"dynamic-put",1,"symbol");
00878 SetEvaluationError(theEnv,TRUE);
00879 return;
00880 }
00881 ins = GetActiveInstance(theEnv);
00882 sp = FindInstanceSlot(theEnv,ins,(SYMBOL_HN *) temp.value);
00883 if (sp == NULL)
00884 {
00885 SlotExistError(theEnv,ValueToString(temp.value),"dynamic-put");
00886 return;
00887 }
00888 if ((sp->desc->noWrite == 0) ? FALSE :
00889 ((sp->desc->initializeOnly == 0) || (!ins->initializeInProgress)))
00890 {
00891 SlotAccessViolationError(theEnv,ValueToString(sp->desc->slotName->name),
00892 TRUE,(void *) ins);
00893 SetEvaluationError(theEnv,TRUE);
00894 return;
00895 }
00896 if ((sp->desc->publicVisibility == 0) &&
00897 (MessageHandlerData(theEnv)->CurrentCore->hnd->cls != sp->desc->cls))
00898 {
00899 SlotVisibilityViolationError(theEnv,sp->desc,MessageHandlerData(theEnv)->CurrentCore->hnd->cls);
00900 SetEvaluationError(theEnv,TRUE);
00901 return;
00902 }
00903 if (GetFirstArgument()->nextArg)
00904 {
00905 if (EvaluateAndStoreInDataObject(theEnv,(int) sp->desc->multiple,
00906 GetFirstArgument()->nextArg,&temp,TRUE) == FALSE)
00907 return;
00908 }
00909 else
00910 {
00911 SetpDOBegin(&temp,1);
00912 SetpDOEnd(&temp,0);
00913 SetpType(&temp,MULTIFIELD);
00914 SetpValue(&temp,ProceduralPrimitiveData(theEnv)->NoParamValue);
00915 }
00916 PutSlotValue(theEnv,ins,sp,&temp,theResult,NULL);
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 static void PerformMessage(
00938 void *theEnv,
00939 DATA_OBJECT *result,
00940 EXPRESSION *args,
00941 SYMBOL_HN *mname)
00942 {
00943 int oldce;
00944
00945 DEFCLASS *cls = NULL;
00946 INSTANCE_TYPE *ins = NULL;
00947 SYMBOL_HN *oldName;
00948 #if PROFILING_FUNCTIONS
00949 struct profileFrameInfo profileFrame;
00950 #endif
00951
00952 result->type = SYMBOL;
00953 result->value = EnvFalseSymbol(theEnv);
00954 EvaluationData(theEnv)->EvaluationError = FALSE;
00955 if (EvaluationData(theEnv)->HaltExecution)
00956 return;
00957 oldce = ExecutingConstruct(theEnv);
00958 SetExecutingConstruct(theEnv,TRUE);
00959 oldName = MessageHandlerData(theEnv)->CurrentMessageName;
00960 MessageHandlerData(theEnv)->CurrentMessageName = mname;
00961 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00962
00963 PushProcParameters(theEnv,args,CountArguments(args),
00964 ValueToString(MessageHandlerData(theEnv)->CurrentMessageName),"message",
00965 UnboundHandlerErr);
00966
00967
00968 if (EvaluationData(theEnv)->EvaluationError)
00969 {
00970 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00971 MessageHandlerData(theEnv)->CurrentMessageName = oldName;
00972 PeriodicCleanup(theEnv,FALSE,TRUE);
00973 SetExecutingConstruct(theEnv,oldce);
00974 return;
00975 }
00976
00977 if (ProceduralPrimitiveData(theEnv)->ProcParamArray->type == INSTANCE_ADDRESS)
00978 {
00979 ins = (INSTANCE_TYPE *) ProceduralPrimitiveData(theEnv)->ProcParamArray->value;
00980 if (ins->garbage == 1)
00981 {
00982 StaleInstanceAddress(theEnv,"send",0);
00983 SetEvaluationError(theEnv,TRUE);
00984 }
00985 else if (DefclassInScope(theEnv,ins->cls,(struct defmodule *) EnvGetCurrentModule(theEnv)) == FALSE)
00986 NoInstanceError(theEnv,ValueToString(ins->name),"send");
00987 else
00988 {
00989 cls = ins->cls;
00990 ins->busy++;
00991 }
00992 }
00993 else if (ProceduralPrimitiveData(theEnv)->ProcParamArray->type == INSTANCE_NAME)
00994 {
00995 ins = FindInstanceBySymbol(theEnv,(SYMBOL_HN *) ProceduralPrimitiveData(theEnv)->ProcParamArray->value);
00996 if (ins == NULL)
00997 {
00998 PrintErrorID(theEnv,"MSGPASS",2,FALSE);
00999 EnvPrintRouter(theEnv,WERROR,"No such instance ");
01000 EnvPrintRouter(theEnv,WERROR,ValueToString((SYMBOL_HN *) ProceduralPrimitiveData(theEnv)->ProcParamArray->value));
01001 EnvPrintRouter(theEnv,WERROR," in function send.\n");
01002 SetEvaluationError(theEnv,TRUE);
01003 }
01004 else
01005 {
01006 ProceduralPrimitiveData(theEnv)->ProcParamArray->value = (void *) ins;
01007 ProceduralPrimitiveData(theEnv)->ProcParamArray->type = INSTANCE_ADDRESS;
01008 cls = ins->cls;
01009 ins->busy++;
01010 }
01011 }
01012 else if ((cls = DefclassData(theEnv)->PrimitiveClassMap[ProceduralPrimitiveData(theEnv)->ProcParamArray->type]) == NULL)
01013 {
01014 SystemError(theEnv,"MSGPASS",1);
01015 EnvExitRouter(theEnv,EXIT_FAILURE);
01016 }
01017 if (EvaluationData(theEnv)->EvaluationError)
01018 {
01019 PopProcParameters(theEnv);
01020 EvaluationData(theEnv)->CurrentEvaluationDepth--;
01021 MessageHandlerData(theEnv)->CurrentMessageName = oldName;
01022 PeriodicCleanup(theEnv,FALSE,TRUE);
01023 SetExecutingConstruct(theEnv,oldce);
01024 return;
01025 }
01026
01027
01028
01029 if (MessageHandlerData(theEnv)->TopOfCore != NULL)
01030 { MessageHandlerData(theEnv)->TopOfCore->nxtInStack = MessageHandlerData(theEnv)->OldCore; }
01031 MessageHandlerData(theEnv)->OldCore = MessageHandlerData(theEnv)->TopOfCore;
01032
01033 MessageHandlerData(theEnv)->TopOfCore = FindApplicableHandlers(theEnv,cls,mname);
01034
01035 if (MessageHandlerData(theEnv)->TopOfCore != NULL)
01036 {
01037 HANDLER_LINK *oldCurrent,*oldNext;
01038
01039 oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
01040 oldNext = MessageHandlerData(theEnv)->NextInCore;
01041
01042 if (MessageHandlerData(theEnv)->TopOfCore->hnd->type == MAROUND)
01043 {
01044 MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->TopOfCore;
01045 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->TopOfCore->nxt;
01046 #if DEBUGGING_FUNCTIONS
01047 if (MessageHandlerData(theEnv)->WatchMessages)
01048 WatchMessage(theEnv,WTRACE,BEGIN_TRACE);
01049 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01050 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
01051 #endif
01052 if (CheckHandlerArgCount(theEnv))
01053 {
01054 #if PROFILING_FUNCTIONS
01055 StartProfile(theEnv,&profileFrame,
01056 &MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
01057 ProfileFunctionData(theEnv)->ProfileConstructs);
01058 #endif
01059
01060
01061 EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
01062 MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
01063 MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
01064 result,UnboundHandlerErr);
01065
01066
01067 #if PROFILING_FUNCTIONS
01068 EndProfile(theEnv,&profileFrame);
01069 #endif
01070 }
01071
01072 #if DEBUGGING_FUNCTIONS
01073 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01074 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
01075 if (MessageHandlerData(theEnv)->WatchMessages)
01076 WatchMessage(theEnv,WTRACE,END_TRACE);
01077 #endif
01078 }
01079 else
01080 {
01081 MessageHandlerData(theEnv)->CurrentCore = NULL;
01082 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->TopOfCore;
01083 #if DEBUGGING_FUNCTIONS
01084 if (MessageHandlerData(theEnv)->WatchMessages)
01085 WatchMessage(theEnv,WTRACE,BEGIN_TRACE);
01086 #endif
01087 CallHandlers(theEnv,result);
01088 #if DEBUGGING_FUNCTIONS
01089 if (MessageHandlerData(theEnv)->WatchMessages)
01090 WatchMessage(theEnv,WTRACE,END_TRACE);
01091 #endif
01092 }
01093
01094 DestroyHandlerLinks(theEnv,MessageHandlerData(theEnv)->TopOfCore);
01095 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
01096 MessageHandlerData(theEnv)->NextInCore = oldNext;
01097 }
01098
01099
01100 MessageHandlerData(theEnv)->TopOfCore = MessageHandlerData(theEnv)->OldCore;
01101 if (MessageHandlerData(theEnv)->OldCore != NULL)
01102 { MessageHandlerData(theEnv)->OldCore = MessageHandlerData(theEnv)->OldCore->nxtInStack; }
01103
01104 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
01105
01106 if (ins != NULL)
01107 ins->busy--;
01108
01109
01110
01111
01112 PopProcParameters(theEnv);
01113 EvaluationData(theEnv)->CurrentEvaluationDepth--;
01114 MessageHandlerData(theEnv)->CurrentMessageName = oldName;
01115 PropagateReturnValue(theEnv,result);
01116 PeriodicCleanup(theEnv,FALSE,TRUE);
01117 SetExecutingConstruct(theEnv,oldce);
01118
01119 if (EvaluationData(theEnv)->EvaluationError)
01120 {
01121 result->type = SYMBOL;
01122 result->value = EnvFalseSymbol(theEnv);
01123 }
01124 }
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 static HANDLER_LINK *FindApplicableHandlers(
01149 void *theEnv,
01150 DEFCLASS *cls,
01151 SYMBOL_HN *mname)
01152 {
01153 register int i;
01154 HANDLER_LINK *tops[4],*bots[4];
01155
01156 for (i = MAROUND ; i <= MAFTER ; i++)
01157 tops[i] = bots[i] = NULL;
01158
01159 for (i = 0 ; i < cls->allSuperclasses.classCount ; i++)
01160 FindApplicableOfName(theEnv,cls->allSuperclasses.classArray[i],tops,bots,mname);
01161 return(JoinHandlerLinks(theEnv,tops,bots,mname));
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183 static void CallHandlers(
01184 void *theEnv,
01185 DATA_OBJECT *result)
01186 {
01187 #if WIN_BTC
01188 HANDLER_LINK *oldCurrent,*oldNext;
01189 #else
01190 HANDLER_LINK *oldCurrent = NULL,*oldNext = NULL;
01191 #endif
01192 DATA_OBJECT temp;
01193 #if PROFILING_FUNCTIONS
01194 struct profileFrameInfo profileFrame;
01195 #endif
01196
01197 if (EvaluationData(theEnv)->HaltExecution)
01198 return;
01199
01200 oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
01201 oldNext = MessageHandlerData(theEnv)->NextInCore;
01202
01203 while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MBEFORE)
01204 {
01205 MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
01206 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
01207 #if DEBUGGING_FUNCTIONS
01208 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01209 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
01210 #endif
01211 if (CheckHandlerArgCount(theEnv))
01212 {
01213 #if PROFILING_FUNCTIONS
01214 StartProfile(theEnv,&profileFrame,
01215 &MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
01216 ProfileFunctionData(theEnv)->ProfileConstructs);
01217 #endif
01218
01219 EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
01220 MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
01221 MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
01222 &temp,UnboundHandlerErr);
01223
01224
01225 #if PROFILING_FUNCTIONS
01226 EndProfile(theEnv,&profileFrame);
01227 #endif
01228 }
01229
01230 #if DEBUGGING_FUNCTIONS
01231 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01232 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
01233 #endif
01234 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
01235 if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
01236 {
01237 MessageHandlerData(theEnv)->NextInCore = oldNext;
01238 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
01239 return;
01240 }
01241 }
01242 if (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY)
01243 {
01244 MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
01245 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
01246 #if DEBUGGING_FUNCTIONS
01247 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01248 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
01249 #endif
01250 if (CheckHandlerArgCount(theEnv))
01251 {
01252 #if PROFILING_FUNCTIONS
01253 StartProfile(theEnv,&profileFrame,
01254 &MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
01255 ProfileFunctionData(theEnv)->ProfileConstructs);
01256 #endif
01257
01258
01259 EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
01260 MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
01261 MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
01262 result,UnboundHandlerErr);
01263
01264 #if PROFILING_FUNCTIONS
01265 EndProfile(theEnv,&profileFrame);
01266 #endif
01267 }
01268
01269
01270 #if DEBUGGING_FUNCTIONS
01271 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01272 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
01273 #endif
01274 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
01275
01276 if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
01277 {
01278 MessageHandlerData(theEnv)->NextInCore = oldNext;
01279 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
01280 return;
01281 }
01282 while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY)
01283 {
01284 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
01285 if (MessageHandlerData(theEnv)->NextInCore == NULL)
01286 {
01287 MessageHandlerData(theEnv)->NextInCore = oldNext;
01288 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
01289 return;
01290 }
01291 }
01292 }
01293 while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MAFTER)
01294 {
01295 MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
01296 MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
01297 #if DEBUGGING_FUNCTIONS
01298 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01299 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
01300 #endif
01301 if (CheckHandlerArgCount(theEnv))
01302 {
01303 #if PROFILING_FUNCTIONS
01304 StartProfile(theEnv,&profileFrame,
01305 &MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
01306 ProfileFunctionData(theEnv)->ProfileConstructs);
01307 #endif
01308
01309
01310 EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
01311 MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
01312 MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
01313 &temp,UnboundHandlerErr);
01314
01315 #if PROFILING_FUNCTIONS
01316 EndProfile(theEnv,&profileFrame);
01317 #endif
01318 }
01319
01320
01321 #if DEBUGGING_FUNCTIONS
01322 if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
01323 WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
01324 #endif
01325 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
01326 if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
01327 {
01328 MessageHandlerData(theEnv)->NextInCore = oldNext;
01329 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
01330 return;
01331 }
01332 }
01333
01334 MessageHandlerData(theEnv)->NextInCore = oldNext;
01335 MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
01336 }
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 static void EarlySlotBindError(
01356 void *theEnv,
01357 INSTANCE_TYPE *theInstance,
01358 DEFCLASS *theDefclass,
01359 unsigned slotID)
01360 {
01361 SLOT_DESC *sd;
01362
01363 sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[slotID] - 1];
01364 PrintErrorID(theEnv,"MSGPASS",3,FALSE);
01365 EnvPrintRouter(theEnv,WERROR,"Static reference to slot ");
01366 EnvPrintRouter(theEnv,WERROR,ValueToString(sd->slotName->name));
01367 EnvPrintRouter(theEnv,WERROR," of class ");
01368 PrintClassName(theEnv,WERROR,theDefclass,FALSE);
01369 EnvPrintRouter(theEnv,WERROR," does not apply to ");
01370 PrintInstanceNameAndClass(theEnv,WERROR,theInstance,TRUE);
01371 }
01372
01373 #endif
01374