Function that checks function context for pointers
| 362 | |
| 363 | // Function that checks function context for pointers |
| 364 | void CheckFunction(char* ptr) |
| 365 | { |
| 366 | NULLCFuncPtr *fPtr = (NULLCFuncPtr*)ptr; |
| 367 | // If there's no context, there's nothing to check |
| 368 | if(!fPtr->context) |
| 369 | return; |
| 370 | const ExternFuncInfo &func = NULLC::commonLinker->exFunctions[fPtr->id]; |
| 371 | // External functions shouldn't be checked |
| 372 | if(func.address == -1) |
| 373 | return; |
| 374 | // If context is "this" pointer |
| 375 | if(func.parentType != ~0u) |
| 376 | { |
| 377 | if(!func.externCount) |
| 378 | { |
| 379 | const ExternTypeInfo &classType = NULLC::commonLinker->exTypes[func.parentType]; |
| 380 | MarkPointer((char*)&fPtr->context, classType, false); |
| 381 | }else{ |
| 382 | MarkPointer((char*)&fPtr->context, NULLC::commonLinker->exTypes[0], false); |
| 383 | // Context is a closure |
| 384 | ExternFuncInfo::Upvalue *upvalue = (ExternFuncInfo::Upvalue*)fPtr->context; |
| 385 | ExternLocalInfo *externals = &NULLC::commonLinker->exLocals[func.offsetToFirstLocal + func.localCount]; |
| 386 | for(unsigned int i = 0; i < func.externCount; i++) |
| 387 | { |
| 388 | ExternTypeInfo &externType = NULLC::commonLinker->exTypes[externals[i].type]; |
| 389 | CheckVariable((char*)upvalue->ptr, externType); |
| 390 | #ifdef _M_X64 |
| 391 | upvalue = (ExternFuncInfo::Upvalue*)((int*)upvalue + ((externals[i].size >> 2) < 4 ? 5 : 2 + (externals[i].size >> 2))); |
| 392 | #else |
| 393 | upvalue = (ExternFuncInfo::Upvalue*)((int*)upvalue + ((externals[i].size >> 2) < 3 ? 3 : 1 + (externals[i].size >> 2))); |
| 394 | #endif |
| 395 | } |
| 396 | } |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | // Function that decides, how variable of type 'type' should be checked for pointers |
| 401 | void CheckVariable(char* ptr, const ExternTypeInfo& type) |
no test coverage detected