| 6461 | |
| 6462 | |
| 6463 | ResultType Script::DefineClassVarInit(LPTSTR aBuf, bool aStatic, Object *aObject, ActionTypeType aActionType) |
| 6464 | { |
| 6465 | Line *script_last_line = mLastLine; |
| 6466 | Line *block_end; |
| 6467 | auto init_func = (UserFunc *)aObject->GetOwnPropMethod(_T("__Init")); // Can only be a user-defined function or nullptr at this stage. |
| 6468 | if (init_func) |
| 6469 | { |
| 6470 | // __Init method already exists, so find the end of its body. |
| 6471 | for (block_end = init_func->mJumpToLine; |
| 6472 | block_end->mActionType != ACT_BLOCK_END || block_end->mAttribute != init_func; |
| 6473 | block_end = block_end->mNextLine); |
| 6474 | } |
| 6475 | else |
| 6476 | { |
| 6477 | // Create an __Init method for this class/prototype. |
| 6478 | init_func = DefineClassInit(aStatic); |
| 6479 | if (!init_func) |
| 6480 | return FAIL; |
| 6481 | script_last_line = block_end = mLastLine; |
| 6482 | } |
| 6483 | |
| 6484 | // Temporarily replace mLastLine to insert script lines at the end of __Init. |
| 6485 | g->CurrentFunc = init_func; // g->CurrentFunc should be NULL prior to this. |
| 6486 | mLastLine = block_end->mPrevLine; // i.e. insert before block_end. |
| 6487 | mLastLine->mNextLine = nullptr; // For maintainability; AddLine() should overwrite it regardless. |
| 6488 | mCurrLine = nullptr; // Fix for v1.1.09.02: Leaving this non-NULL at best causes error messages to show irrelevant vicinity lines, and at worst causes a crash because the linked list is in an inconsistent state. |
| 6489 | |
| 6490 | Line *prl = mPendingRelatedLine; // This was set by AddLine(ACT_BLOCK_END) if DefineClassInit() was just called. |
| 6491 | mPendingRelatedLine = nullptr; |
| 6492 | mNoUpdateLabels = true; |
| 6493 | if (!ParseAndAddLine(aBuf, aActionType)) |
| 6494 | return FAIL; // Above already displayed the error. |
| 6495 | mNoUpdateLabels = false; |
| 6496 | mPendingRelatedLine = prl; |
| 6497 | |
| 6498 | if (init_func->mJumpToLine == block_end) // This can be true only for the first static initializer. |
| 6499 | init_func->mJumpToLine = mLastLine; |
| 6500 | // Rejoin the function's block-end (and any lines following it) to the main script. |
| 6501 | mLastLine->mNextLine = block_end; |
| 6502 | block_end->mPrevLine = mLastLine; |
| 6503 | // mFirstLine should be left as it is: if it was NULL, it now contains a pointer to our |
| 6504 | // __init function's block-begin, which is now the very first executable line in the script. |
| 6505 | g->CurrentFunc = nullptr; |
| 6506 | // Restore mLastLine so that any subsequent script lines are added at the correct point. |
| 6507 | mLastLine = script_last_line; |
| 6508 | return OK; |
| 6509 | } |
| 6510 | |
| 6511 | |
| 6512 | UserFunc *Script::DefineClassInit(bool aStatic) |
nothing calls this directly
no test coverage detected