int p_member(value velt, type telt, value vlist, type tlist) { pword *p; /* we require a list or nil */ Check_List(tlist); /* if the list is empty, we fail */ if(IsNil(tlist)) { Fail; } /* the tail of the list */ p = vlist.ptr + 1; /* must be dereferenced! */ Dereference(p); /* * on backtracking we will get the tail of the list * instead of the list itself */ Remember(2, p->val, p->tag); /* * and we behave as the unification * of the element and the head */ Return_Unify_Pw(velt, telt, vlist.ptr->val, vlist.ptr->tag); }
void OGRFeatureDefn::Release() { CPLAssert( NULL != this ); if( Dereference() <= 0 ) delete this; }
wxInt32 wxGISPointer::Release(void) { Dereference(); if (m_RefCount < 1) { delete this; return 0; } else { return m_RefCount; } }
void cMonster::EventLosePlayer(void) { Dereference(m_Target); m_Target = NULL; m_EMState = IDLE; }
void Thread::Run() { handler->FireData(this); Dereference(); }
uint32 InterpretedVM::Execute(Function* func) { prog.CurrentFunction = func; int pc = 0; for (;;) { auto op = func->Ops[pc]; switch (op.Op) { case Op::OpBranch: { auto branch = (SBranch*)op.Memory; pc = func->Labels.at(branch->TargetLabelId); break; } case Op::OpBranchConditional: { auto branch = (SBranchConditional*)op.Memory; uint32 labelID; Value val = Dereference(env.Values[branch->ConditionId]); if (*(bool*)val.Memory) { labelID = branch->TrueLabelId; } else { labelID = branch->FalseLabelId; } pc = func->Labels.at(labelID); break; } case Op::OpFunctionCall: { auto call = (SFunctionCall*)op.Memory; Function toCall = prog.FunctionDefinitions.at(call->FunctionId); for (int i = 0; i < call->ArgumentIdsCount; i++) { env.Values[toCall.Parameters[i].ResultId] = Dereference(env.Values.at(call->ArgumentIds[i])); } uint32 resultId = Execute(&toCall); if (resultId == -1) { return -1; } prog.CurrentFunction = func; env.Values[call->ResultId] = env.Values[resultId]; break; } case Op::OpExtInst: { auto extInst = (SExtInst*)op.Memory; Value* ops = new Value[extInst->OperandIdsCount]; for (int i = 0; i < extInst->OperandIdsCount; i++) { ops[i] = Dereference(env.Values.at(extInst->OperandIds[i])); } ExtInstFunc* func = env.Extensions[extInst->SetId][extInst->Instruction]; env.Values[extInst->ResultId] = func(this, extInst->ResultTypeId, extInst->OperandIdsCount, ops); break; } case Op::OpConvertSToF: { auto convert = (SConvertSToF*)op.Memory; Value op1 = Dereference(env.Values[convert->SignedValueId]); env.Values[convert->ResultId] = DoOp(convert->ResultTypeId, Convert<int32, float>, op1); break; } case Op::OpFAdd: { auto add = (SFAdd*)op.Memory; Value op1 = Dereference(env.Values[add->Operand1Id]); Value op2 = Dereference(env.Values[add->Operand2Id]); env.Values[add->ResultId] = DoOp(add->ResultTypeId, Add<float>, op1, op2); break; } case Op::OpIAdd: { auto add = (SIAdd*)op.Memory; Value op1 = Dereference(env.Values[add->Operand1Id]); Value op2 = Dereference(env.Values[add->Operand2Id]); env.Values[add->ResultId] = DoOp(add->ResultTypeId, Add<int>, op1, op2); break; } case Op::OpFSub: { auto sub = (SFSub*)op.Memory; Value op1 = Dereference(env.Values[sub->Operand1Id]); Value op2 = Dereference(env.Values[sub->Operand2Id]); env.Values[sub->ResultId] = DoOp(sub->ResultTypeId, Sub<float>, op1, op2); break; } case Op::OpISub: { auto sub = (SISub*)op.Memory; Value op1 = Dereference(env.Values[sub->Operand1Id]); Value op2 = Dereference(env.Values[sub->Operand2Id]); env.Values[sub->ResultId] = DoOp(sub->ResultTypeId, Sub<int>, op1, op2); break; } case Op::OpFDiv: { auto div = (SFDiv*)op.Memory; Value op1 = Dereference(env.Values[div->Operand1Id]); Value op2 = Dereference(env.Values[div->Operand2Id]); env.Values[div->ResultId] = DoOp(div->ResultTypeId, Div<float>, op1, op2); break; } case Op::OpFMul: { auto mul = (SFMul*)op.Memory; Value op1 = Dereference(env.Values[mul->Operand1Id]); Value op2 = Dereference(env.Values[mul->Operand2Id]); env.Values[mul->ResultId] = DoOp(mul->ResultTypeId, Mul<float>, op1, op2); break; } case Op::OpIMul: { auto mul = (SFMul*)op.Memory; Value op1 = Dereference(env.Values[mul->Operand1Id]); Value op2 = Dereference(env.Values[mul->Operand2Id]); env.Values[mul->ResultId] = DoOp(mul->ResultTypeId, Mul<int>, op1, op2); break; } case Op::OpVectorTimesScalar: { auto vts = (SVectorTimesScalar*)op.Memory; Value scalar = Dereference(env.Values[vts->ScalarId]); Value vector = Dereference(env.Values[vts->VectorId]); env.Values[vts->ResultId] = DoOp(vts->ResultTypeId, [scalar](Value comp) {return Mul<float>(scalar, comp);}, vector); break; } case Op::OpSLessThan: { auto lessThan = (SSLessThan*)op.Memory; Value op1 = Dereference(env.Values[lessThan->Operand1Id]); Value op2 = Dereference(env.Values[lessThan->Operand2Id]); env.Values[lessThan->ResultId] = DoOp(lessThan->ResultTypeId, [](Value a, Value b) { return Cmp<int32>(a, b) == -1; }, op1, op2); break; } case Op::OpSGreaterThan: { auto greaterThan = (SSLessThan*)op.Memory; Value op1 = Dereference(env.Values[greaterThan->Operand1Id]); Value op2 = Dereference(env.Values[greaterThan->Operand2Id]); env.Values[greaterThan->ResultId] = DoOp(greaterThan->ResultTypeId, [](Value a, Value b) { return Cmp<int32>(a, b) == 1; }, op1, op2); break; } case Op::OpLoad: { auto load = (SLoad*)op.Memory; auto valueToLoad = env.Values.at(load->PointerId); env.Values[load->ResultId] = valueToLoad; break; } case Op::OpStore: { auto store = (SStore*)op.Memory; auto val = env.Values[store->ObjectId]; auto var = GetType(val.TypeId); if (var.Op == Op::OpTypePointer) { SetVariable(store->PointerId, val.Memory); } else { SetVariable(store->PointerId, &val.Memory); } break; } case Op::OpTextureSample: { auto sample = (STextureSample*)op.Memory; auto sampler = Dereference(env.Values.at(sample->SamplerId)); auto coord = Dereference(env.Values.at(sample->CoordinateId)); Value bias = { 0, 0 }; if (sample->BiasId != 0) { bias = Dereference(env.Values.at(sample->BiasId)); } env.Values[sample->ResultId] = TextureSample(sampler, coord, bias, sample->ResultTypeId); break; } case Op::OpLabel: case Op::OpSelectionMerge: case Op::OpLoopMerge: break; case Op::OpAccessChain: { auto access = (SAccessChain*)op.Memory; auto val = Dereference(env.Values.at(access->BaseId)); uint32* indices = new uint32[access->IndexesIdsCount]; for (int i = 0; i < access->IndexesIdsCount; i++) { indices[i] = *(uint32*)Dereference(env.Values[access->IndexesIds[i]]).Memory; } byte* mem = GetPointerInComposite(val.TypeId, val.Memory, access->IndexesIdsCount, indices); delete indices; Value res = VmInit(access->ResultTypeId, &mem); env.Values[access->ResultId] = res; break; } case Op::OpVectorShuffle: { auto vecShuffle = (SVectorShuffle*)op.Memory; auto vec1 = Dereference(env.Values.at(vecShuffle->Vector1Id)); auto vec2 = Dereference(env.Values.at(vecShuffle->Vector2Id)); auto result = VmInit(vecShuffle->ResultTypeId, nullptr); int v1ElCount = ElementCount(vec1.TypeId); for (int i = 0; i < vecShuffle->ComponentsCount; i++) { int index = vecShuffle->Components[i]; Value toCopy; if (index < v1ElCount) { toCopy = vec1; } else { index -= v1ElCount; toCopy = vec2; } Value elToCopy = IndexMemberValue(toCopy, index); memcpy(IndexMemberValue(result, i).Memory, elToCopy.Memory, GetTypeByteSize(elToCopy.TypeId)); } env.Values[vecShuffle->ResultId] = result; break; } //TODO: FIX INDICES (NOT HIERARCHY!) case Op::OpCompositeExtract: { auto extract = (SCompositeExtract*)op.Memory; auto composite = env.Values[extract->CompositeId]; byte* mem = GetPointerInComposite(composite.TypeId, composite.Memory, extract->IndexesCount, extract->Indexes); Value val = { extract->ResultTypeId, VmAlloc(extract->ResultTypeId) }; memcpy(val.Memory, mem, GetTypeByteSize(val.TypeId)); env.Values[extract->ResultId] = val; break; } case Op::OpCompositeInsert: { auto insert = (SCompositeInsert*)op.Memory; auto composite = Dereference(env.Values[insert->CompositeId]); Value val = Dereference(env.Values.at(insert->ObjectId)); byte* mem = GetPointerInComposite(composite.TypeId, composite.Memory, insert->IndexesCount, insert->Indexes); memcpy(mem, val.Memory, GetTypeByteSize(val.TypeId)); env.Values[insert->ResultId] = VmInit(composite.TypeId, composite.Memory); break; } case Op::OpCompositeConstruct: { auto construct = (SCompositeConstruct*)op.Memory; Value val = { construct->ResultTypeId, VmAlloc(construct->ResultTypeId) }; env.Values[construct->ResultId] = val; byte* memPtr = val.Memory; for (int i = 0; i < construct->ConstituentsIdsCount; i++) { auto memVal = env.Values[construct->ConstituentsIds[i]]; uint32 memSize = GetTypeByteSize(memVal.TypeId); memcpy(memPtr, memVal.Memory, memSize); memPtr += memSize; } assert(memPtr - val.Memory == GetTypeByteSize(construct->ResultTypeId)); break; } case Op::OpVariable: { auto var = (SVariable*)op.Memory; Value val = { var->ResultTypeId, VmAlloc(var->ResultTypeId) }; if (var->InitializerId) { memcpy(val.Memory, env.Values[var->InitializerId].Memory, GetTypeByteSize(val.TypeId)); } else { memset(val.Memory, 0, GetTypeByteSize(val.TypeId)); } env.Values[var->ResultId] = val; break; } case Op::OpReturnValue: { auto ret = (SReturnValue*)op.Memory; return ret->ValueId; } case Op::OpReturn: return 0; default: std::cout << "Unimplemented operation: " << writeOp(op); return -1; } pc++; } return 0; }
void OGRFeatureDefn::Release() { if( this && Dereference() == 0 ) delete this; }