void assignBuildCommands() { BOOL okToFreeList = TRUE; BOOL fFirstTarg = (BOOL)TRUE; STRINGLIST *p; const char *which = NULL; if (ON(actionFlags, A_RULE)) // no macros found yet for inference rules rules->buildCommands = list; else if (ON(actionFlags, A_SILENT) || ON(actionFlags, A_IGNORE) || ON(actionFlags, A_PRECIOUS) || ON(actionFlags, A_SUFFIX) ) { if (list) { if (ON(actionFlags, A_SILENT)) which = silent; else if (ON(actionFlags, A_IGNORE)) which = ignore; else if (ON(actionFlags, A_PRECIOUS)) which = precious; else if (ON(actionFlags, A_SUFFIX)) which = suffixes; makeError(currentLine, CMDS_ON_PSEUDO, which); } } else { block->buildCommands = list; block->buildMacros = macros; block->flags = currentFlags; while ((p = targetList)) { // make a struct for each targ if (doSpecial(p->text)) // in list, freeing list when makeError(currentLine, MIXED_TARGETS); makeTarget(p->text, fFirstTarg, &block); // done, don't free name if (!makeTargets) { // field -- it's still in use makeTargets = p; // if no targs given on cmdlin okToFreeList = FALSE; // put first target(s) from } // mkfile in makeTargets list targetList = p->next; // (makeTargets defined in if (okToFreeList) // nmake.c) FREE_STRINGLIST(p); if (fFirstTarg) fFirstTarg = (BOOL)FALSE; } } targetList = NULL; list = NULL; macros = NULL; block = NULL; actionFlags = 0; }
void endNameList() { if (name) { // if only one name to left of : startNameList(); // it hasn't been put in list yet name = NULL; } else CLEAR(actionFlags, A_TARGET); // clear target flag if (buf[1]) SET(currentFlags, F2_DOUBLECOLON); // so addItemToList() if (!list) // won't expand names makeError(currentLine, SYNTAX_NO_TARGET_NAME); // of dependents if (ON(actionFlags, A_RULE)) { BOOL fBatch; // A rule with a doublecolon on the dependency line // is a "batch rule", i.e., a rule that applies the // command block in batch mode for all affected // dependents. fBatch = !!(ON(currentFlags, F2_DOUBLECOLON)); makeRule(list, fBatch); FREE_STRINGLIST(list); } else if (!(list->next) && doSpecial(list->text)) { // special pseudotarget ... FREE(list->text); // don't need ".SUFFIXES" etc FREE_STRINGLIST(list); } else // regular target targetList = list; list = NULL; // We are now looking for a dependent SET(actionFlags, A_DEPENDENT); }
SmalltalkVM::TExecuteResult SmalltalkVM::execute(TProcess* p, uint32_t ticks) { // Protecting the process pointer hptr<TProcess> currentProcess = newPointer(p); assert(currentProcess->context != 0); assert(currentProcess->context->method != 0); // Initializing an execution context TVMExecutionContext ec(m_memoryManager, this); ec.currentContext = currentProcess->context; ec.loadPointers(); // Loads bytePointer & stackTop while (true) { assert(ec.currentContext != 0); assert(ec.currentContext->method != 0); assert(ec.currentContext->stack != 0); assert(ec.bytePointer <= ec.currentContext->method->byteCodes->getSize()); assert(ec.currentContext->arguments->getSize() >= 1); assert(ec.currentContext->arguments->getField(0) != 0); // Initializing helper references TByteObject& byteCodes = * ec.currentContext->method->byteCodes; TObjectArray& temporaries = * ec.currentContext->temporaries; TObjectArray& arguments = * ec.currentContext->arguments; TObjectArray& instanceVariables = * arguments.getField<TObjectArray>(0); TSymbolArray& literals = * ec.currentContext->method->literals; if (ticks && (--ticks == 0)) { // Time frame expired ec.storePointers(); currentProcess->context = ec.currentContext; currentProcess->result = ec.returnedValue; return returnTimeExpired; } // Decoding the instruction const uint16_t lastBytePointer = ec.bytePointer; ec.instruction = st::InstructionDecoder::decodeAndShiftPointer(byteCodes, ec.bytePointer); // And executing it switch (ec.instruction.getOpcode()) { case opcode::pushInstance: ec.stackPush(instanceVariables[ec.instruction.getArgument()]); break; case opcode::pushArgument: ec.stackPush(arguments[ec.instruction.getArgument()]); break; case opcode::pushTemporary: ec.stackPush(temporaries[ec.instruction.getArgument()]); break; case opcode::pushLiteral: ec.stackPush(literals[ec.instruction.getArgument()]); break; case opcode::pushConstant: doPushConstant(ec); break; case opcode::pushBlock: doPushBlock(ec); break; case opcode::assignTemporary: temporaries[ec.instruction.getArgument()] = ec.stackLast(); break; case opcode::assignInstance: { TObject* newValue = ec.stackLast(); TObject** objectSlot = & instanceVariables[ec.instruction.getArgument()]; // Checking whether we need to register current object slot in the GC checkRoot(newValue, objectSlot); // Performing the assignment *objectSlot = newValue; } break; case opcode::markArguments: doMarkArguments(ec); break; case opcode::sendMessage: doSendMessage(ec); break; case opcode::sendUnary: doSendUnary(ec); break; case opcode::sendBinary: doSendBinary(ec); break; case opcode::doPrimitive: { TExecuteResult result = doPrimitive(currentProcess, ec); if (result != returnNoReturn) return result; } break; case opcode::doSpecial: { TExecuteResult result = doSpecial(currentProcess, ec); if (result != returnNoReturn) return result; } break; default: std::fprintf(stderr, "VM: Invalid opcode %d at offset %d in method ", ec.instruction.getOpcode(), lastBytePointer); std::fprintf(stderr, "'%s'\n", ec.currentContext->method->name->toString().c_str() ); std::exit(1); } } }