bool SetVariableCommand::setConstant( DebuggerSession* session, const std::string& name, const std::string& value, ScopeObject* scope, folly::dynamic* result ) { const auto& constants = lookupDefinedConstants(false); for (ArrayIter iter(constants); iter; ++iter) { const std::string constantName = iter.first().toString().toCppString(); if (constantName == name) { TypedValue* constantValue = iter.second().asTypedValue(); setVariableValue( session, name, value, constantValue, scope->m_requestId, result ); return true; } } return false; }
bool SetVariableCommand::setObjectVariable( DebuggerSession* session, const std::string& name, const std::string& value, VariableObject* object, folly::dynamic* result ) { Variant& var = object->m_variable; assertx(var.isObject()); HPHP::String key(name); ObjectData* obj = var.getObjectData(); Variant currentValue = obj->o_get(key, false); if (!currentValue.isInitialized()) { throw DebuggerCommandException( "Failed to set variable: Property not found on object." ); } TypedValue* propValue = currentValue.asTypedValue(); setVariableValue( session, name, value, propValue, object->m_requestId, result ); obj->o_set(key, currentValue); return true; }
bool SetVariableCommand::setLocalVariable( DebuggerSession* session, const std::string& name, const std::string& value, ScopeObject* scope, folly::dynamic* result ) { VMRegAnchor regAnchor; const auto fp = g_context->getFrameAtDepth(scope->m_frameDepth); const auto func = fp->m_func; const auto localCount = func->numNamedLocals(); for (Id id = 0; id < localCount; id++) { TypedValue* frameValue = frame_local(fp, id); const std::string localName = func->localVarName(id)->toCppString(); if (localName == name) { setVariableValue( session, name, value, frameValue, scope->m_requestId, result ); return true; } } return false; }
static unsigned int handleLet(char * assembled, unsigned int currentPoint, unsigned int length, char restrictNoAlias, int threadId) { #else static unsigned int handleLet(char * assembled, unsigned int currentPoint, unsigned int length, char restrictNoAlias) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, fnLevel[threadId], threadId, 1); struct value_defn value=getExpressionValue(assembled, ¤tPoint, length, threadId); if (restrictNoAlias && getVariableSymbol(varId, fnLevel[threadId], threadId, 0)->state==ALIAS) return currentPoint; #else struct symbol_node* variableSymbol=getVariableSymbol(varId, fnLevel, 1); struct value_defn value=getExpressionValue(assembled, ¤tPoint, length); if (restrictNoAlias && getVariableSymbol(varId, fnLevel, 0)->state==ALIAS) return currentPoint; #endif variableSymbol->value.type=value.type; variableSymbol->value.dtype=value.dtype; if (value.dtype == ARRAY) { cpy(variableSymbol->value.data, value.data, sizeof(char*)); } else if (value.type == STRING_TYPE) { cpy(&variableSymbol->value.data, &value.data, sizeof(char*)); } else { int currentAddress=getInt(variableSymbol->value.data); if (currentAddress == 0) { char * address=getStackMemory(sizeof(int), 0); cpy(variableSymbol->value.data, &address, sizeof(char*)); cpy(address, value.data, sizeof(int)); } else { setVariableValue(variableSymbol, value, -1); } } return currentPoint; }
static unsigned int handleArraySet(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) { #else static unsigned int handleArraySet(char * assembled, unsigned int currentPoint, unsigned int length) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, fnLevel[threadId], threadId, 1); int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, ¤tPoint, length, threadId); struct value_defn value=getExpressionValue(assembled, ¤tPoint, length, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId, fnLevel, 1); int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, ¤tPoint, length); struct value_defn value=getExpressionValue(assembled, ¤tPoint, length); #endif setVariableValue(variableSymbol, value, targetIndex); return currentPoint; }
bool SetVariableCommand::setArrayVariable( DebuggerSession* session, const std::string& name, const std::string& value, VariableObject* array, folly::dynamic* result ) { VMRegAnchor regAnchor; Variant& var = array->m_variable; assertx(var.isArray()); Array arr = var.toArray(); for (ArrayIter iter(arr); iter; ++iter) { std::string indexName = iter.first().toString().toCppString(); if (indexName == name) { TypedValue* arrayValue = iter.second().asTypedValue(); setVariableValue( session, name, value, arrayValue, array->m_requestId, result ); auto keyVariant = iter.first(); if (keyVariant.isString()) { HPHP::String key = keyVariant.toString(); arr->set(key, tvToInitCell(*arrayValue), false); } else if (keyVariant.isInteger()) { int64_t key = keyVariant.toInt64(); arr->set(key, tvToInitCell(*arrayValue), false); } else { throw DebuggerCommandException("Unsupported array key type."); } return true; } } return false; }
static unsigned int handleGoto(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) { #else static unsigned int handleGoto(char * assembled, unsigned int currentPoint, unsigned int length) { #endif return getUShort(&assembled[currentPoint]); } #ifdef HOST_INTERPRETER static unsigned int handleNative(char * assembled, unsigned int currentPoint, unsigned int length, struct value_defn * returnValue, int threadId) { #else static unsigned int handleNative(char * assembled, unsigned int currentPoint, unsigned int length, struct value_defn * returnValue) { #endif unsigned char fnCode=getUChar(&assembled[currentPoint]); currentPoint+=sizeof(unsigned char); unsigned short numArgs=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); struct value_defn toPassValues[numArgs]; int i; for (i=0; i<numArgs; i++) { #ifdef HOST_INTERPRETER toPassValues[i]=getExpressionValue(assembled, ¤tPoint, length, threadId); #else toPassValues[i]=getExpressionValue(assembled, ¤tPoint, length); #endif } if (returnValue != NULL) { #ifdef HOST_INTERPRETER callNativeFunction(returnValue, fnCode, numArgs, toPassValues, numActiveCores[threadId], localCoreId[threadId], currentSymbolEntries[threadId], symbolTable[threadId], threadId); #else callNativeFunction(returnValue, fnCode, numArgs, toPassValues, numActiveCores, localCoreId, currentSymbolEntries, symbolTable); #endif } else { struct value_defn dummy; #ifdef HOST_INTERPRETER callNativeFunction(&dummy, fnCode, numArgs, toPassValues, numActiveCores[threadId], localCoreId[threadId], currentSymbolEntries[threadId], symbolTable[threadId], threadId); #else callNativeFunction(&dummy, fnCode, numArgs, toPassValues, numActiveCores, localCoreId, currentSymbolEntries, symbolTable); #endif } return currentPoint; } /** * Calls some function and stores the call point in the function call stack for returning from this function */ #ifdef HOST_INTERPRETER static unsigned int handleFnCall(char * assembled, unsigned int currentPoint, unsigned int * functionAddress, unsigned int length, char calledByVar, int threadId) { #else static unsigned int handleFnCall(char * assembled, unsigned int currentPoint, unsigned int * functionAddress, unsigned int length, char calledByVar) { #endif unsigned short fnAddress; if (calledByVar) { #ifdef HOST_INTERPRETER struct symbol_node* callVar=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel[threadId], threadId, 1); #else struct symbol_node* callVar=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel, 1); #endif if (callVar->value.type != FN_ADDR_TYPE) raiseError(ERR_FNCALL_VAR_NOT_CONTAINING_FN_PTR); char *ptr; cpy(&ptr, callVar->value.data, sizeof(char*)); fnAddress=getUShort(ptr); } else { fnAddress=getUShort(&assembled[currentPoint]); } currentPoint+=sizeof(unsigned short); unsigned short fnNumArgs=getUShort(&assembled[fnAddress]); fnAddress+=sizeof(unsigned short); unsigned short callerNumArgs=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); struct symbol_node* srcSymbol, *targetSymbol; int i, numArgs; numArgs=fnNumArgs > callerNumArgs ? fnNumArgs : callerNumArgs; for (i=0; i<numArgs; i++) { if (i<callerNumArgs && i<fnNumArgs) { #ifdef HOST_INTERPRETER srcSymbol=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel[threadId], threadId, 0); targetSymbol=getVariableSymbol(getUShort(&assembled[fnAddress]), fnLevel[threadId]+1, threadId, 0); #else srcSymbol=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel, 0); targetSymbol=getVariableSymbol(getUShort(&assembled[fnAddress]), fnLevel+1, 0); #endif targetSymbol->state=ALIAS; targetSymbol->alias=srcSymbol->id; } if (i<callerNumArgs) currentPoint+=sizeof(unsigned short); if (i<fnNumArgs) fnAddress+=sizeof(unsigned short); } *functionAddress=fnAddress; return currentPoint; } /** * Loop iteration */ #ifdef HOST_INTERPRETER static unsigned int handleFor(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) { #else static unsigned int handleFor(char * assembled, unsigned int currentPoint, unsigned int length) { #endif unsigned short loopIncrementerId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); unsigned short loopVariantId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* incrementVarSymbol=getVariableSymbol(loopIncrementerId, fnLevel[threadId], threadId, 1); struct symbol_node* variantVarSymbol=getVariableSymbol(loopVariantId, fnLevel[threadId], threadId, 1); struct value_defn expressionVal=getExpressionValue(assembled, ¤tPoint, length, threadId); #else struct symbol_node* incrementVarSymbol=getVariableSymbol(loopIncrementerId, fnLevel, 1); struct symbol_node* variantVarSymbol=getVariableSymbol(loopVariantId, fnLevel, 1); struct value_defn expressionVal=getExpressionValue(assembled, ¤tPoint, length); #endif unsigned short blockLen=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); char * ptr; int singleSize, arrSize=1, i, headersize; unsigned char numDims; cpy(&ptr, expressionVal.data, sizeof(char*)); cpy(&numDims, ptr, sizeof(unsigned char)); numDims=numDims & 0xF; for (i=0; i<numDims; i++) { cpy(&singleSize, &ptr[1+(i*sizeof(unsigned int))], sizeof(unsigned int)); arrSize*=singleSize; } headersize=sizeof(unsigned char) + (sizeof(unsigned int) * numDims); struct value_defn varVal=getVariableValue(incrementVarSymbol, -1); int incrementVal=getInt(varVal.data); if (incrementVal < arrSize) { struct value_defn nextElement; nextElement.type=expressionVal.type; cpy(&nextElement.data, ptr+((incrementVal*sizeof(int)) + headersize), sizeof(int)); setVariableValue(variantVarSymbol, nextElement, -1); return currentPoint; } currentPoint+=(blockLen+sizeof(unsigned short)+sizeof(unsigned char)); return currentPoint; } /** * Conditional, with or without else block */ #ifdef HOST_INTERPRETER static unsigned int handleIf(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) { int conditionalResult=determine_logical_expression(assembled, ¤tPoint, length, threadId); #else static unsigned int handleIf(char * assembled, unsigned int currentPoint, unsigned int length) { int conditionalResult=determine_logical_expression(assembled, ¤tPoint, length); #endif if (conditionalResult) return currentPoint+sizeof(unsigned short); unsigned short blockLen=getUShort(&assembled[currentPoint]); return currentPoint+sizeof(unsigned short)+blockLen; }