bool Stack::isUserTypeAt(int index, const Common::UString &type) const { if (type.empty()) { return getTypeAt(index) == kTypeUserType; } tolua_Error error; return checkIndex(index) && tolua_isusertype(&_luaState, index, type.c_str(), 0, &error) != 0; }
Variable Stack::getVariableAt(int index) const { switch (getTypeAt(index)) { case kTypeNil: return Variable(kTypeNil); case kTypeBoolean: return getBooleanAt(index); case kTypeNumber: return getFloatAt(index); case kTypeString: return getStringAt(index); case kTypeTable: return getTableAt(index); case kTypeFunction: return getFunctionAt(index); case kTypeUserType: { const Common::UString exactType = getExactTypeAt(index); return Variable(getRawUserTypeAt(index, exactType), exactType); } default: return Variable(kTypeNone); } }
void Stack::registerGCForTopObject() { assert(getTypeAt(getSize()) == kTypeUserType); tolua_register_gc(&_luaState, getSize()); }
/** * Appends a new function statement to the function list which is held by the memory manager. * This also appends a return statement to the end of the function body and registers * the current goto point as the function name */ void appendNewFunctionStatement(char* functionName, struct stack_t * args, struct memorycontainer* functionContents) { struct functionDefinition * fn=(struct functionDefinition*) malloc(sizeof(struct functionDefinition)); fn->name=(char*) malloc(strlen(functionName) + 1); strcpy(fn->name, functionName); fn->called=0; unsigned short numberArgs=(unsigned short) getStackSize(args); struct memorycontainer* numberArgsContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); numberArgsContainer->length=sizeof(unsigned short) * (numberArgs + 1); numberArgsContainer->data=(char*) malloc(sizeof(unsigned short) * (numberArgs + 1)); numberArgsContainer->lineDefns=NULL; ((unsigned short *) numberArgsContainer->data)[0]=numberArgs; struct memorycontainer* assignmentContainer=NULL; int i; for (i=0;i<numberArgs;i++) { if (getTypeAt(args, i) == 2) { ((unsigned short *) numberArgsContainer->data)[i+1]=getVariableId(getIdentifierAt(args, i), 1); } else { struct identifier_exp * idexp=getExpressionIdentifierAt(args, i); if (assignmentContainer == NULL) { assignmentContainer=appendLetIfNoAliasStatement(idexp->identifier, idexp->exp); } else { assignmentContainer=concatenateMemory(assignmentContainer, appendLetIfNoAliasStatement(idexp->identifier, idexp->exp)); } ((unsigned short *) numberArgsContainer->data)[i+1]=getVariableId(idexp->identifier, 1); } } clearStack(args); if (assignmentContainer != NULL) numberArgsContainer=concatenateMemory(numberArgsContainer, assignmentContainer); struct memorycontainer* completedFunction=concatenateMemory(concatenateMemory(numberArgsContainer, functionContents), appendReturnStatement()); struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=completedFunction->lineDefns; defn->type=2; defn->currentpoint=0; defn->name=(char*) malloc(strlen(functionName) + 1); strcpy(defn->name, functionName); completedFunction->lineDefns=defn; fn->contents=completedFunction; fn->numberEntriesInSymbolTable=current_var_id - currentSymbolTableId; fn->recursive=isFnRecursive; fn->number_of_fn_calls=currentCall->number_of_calls; if (currentCall->number_of_calls == 0) { fn->functionCalls=NULL; } else { fn->functionCalls=(char**) malloc(sizeof(char*) * currentCall->number_of_calls); memcpy(fn->functionCalls, currentCall->calledFunctions, sizeof(char*) * currentCall->number_of_calls); } free(currentFunctionName); currentFunctionName=NULL; currentCall=NULL; addFunction(fn); }