| 574 | } |
| 575 | |
| 576 | void asCCompiler::CompileMemberInitializationCopy(asCByteCode* bc) |
| 577 | { |
| 578 | asASSERT(m_classDecl); |
| 579 | |
| 580 | // Initialize each member in the order they were declared. Skip members inherited |
| 581 | // from a base class, as they will be taken care of by the base class' constructor |
| 582 | for (asUINT n = 0; n < outFunc->objectType->properties.GetLength(); n++) |
| 583 | { |
| 584 | asCObjectProperty* prop = outFunc->objectType->properties[n]; |
| 585 | |
| 586 | // Check if the property is inherited |
| 587 | asCScriptNode* declNode = 0; |
| 588 | for (asUINT m = 0; m < m_classDecl->propInits.GetLength(); m++) |
| 589 | { |
| 590 | if (m_classDecl->propInits[m].name == prop->name) |
| 591 | { |
| 592 | declNode = m_classDecl->propInits[m].declNode; |
| 593 | break; |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | // If declNode is null then the property was inherited |
| 598 | if (declNode) |
| 599 | { |
| 600 | // Add a line instruction with the position of the declaration |
| 601 | LineInstr(bc, declNode->tokenPos); |
| 602 | |
| 603 | // Compile the initialization as a copy |
| 604 | asCExprContext ctx(engine); |
| 605 | CompileVariableAccess("other", "", &ctx, 0); |
| 606 | ctx.bc.Instr(asBC_RDSPtr); |
| 607 | |
| 608 | // Code is similar to CompileExprPostOp for the ttDot operator |
| 609 | // TODO: cleanup: Make a reusable method for both CompileExprPostOp with ttDot and here |
| 610 | ctx.bc.InstrSHORT_DW(asBC_ADDSi, (short)prop->byteOffset, engine->GetTypeIdFromDataType(asCDataType::CreateType(outFunc->objectType, false))); |
| 611 | if (prop->type.IsReference()) |
| 612 | ctx.bc.Instr(asBC_RDSPtr); |
| 613 | |
| 614 | // Reference to primitive must be stored in the temp register |
| 615 | if (prop->type.IsPrimitive()) |
| 616 | ctx.bc.Instr(asBC_PopRPtr); |
| 617 | |
| 618 | // Set the new type and make sure it is not treated as a variable anymore |
| 619 | ctx.type.dataType = prop->type; |
| 620 | ctx.type.dataType.MakeReference(true); |
| 621 | ctx.type.isVariable = false; |
| 622 | ctx.type.isTemporary = false; |
| 623 | |
| 624 | if ((ctx.type.dataType.IsObject() || ctx.type.dataType.IsFuncdef()) && !ctx.type.dataType.IsObjectHandle()) |
| 625 | { |
| 626 | // Objects that are members are not references |
| 627 | ctx.type.dataType.MakeReference(false); |
| 628 | |
| 629 | // The object is safe (life time guaranteed) if the parent object is also safe |
| 630 | } |
| 631 | else if (ctx.type.dataType.IsObjectHandle()) |
| 632 | { |
| 633 | // A object accessed through a handle cannot be considered safe, |
nothing calls this directly
no test coverage detected