суббота, 2 февраля 2013 г.

определение количества cd-rom assembler

void SmalltalkVM::doPushBlock(TVMExecutionContext& ec) { hptr<TByteObject> byteCodes = newPointer(ec.currentContext->method->byteCodes); hptr<TObjectArray> stack = newPointer(ec.currentContext->stack); // Block objects are usually inlined in the wrapping method code // pushBlock operation creates a block object initialized // with the proper bytecode, stack, arguments and the wrapping context. // Blocks are not executed directly. Instead they should be invoked // by sending them a 'value' method. Thus, all we need to do here is initialize // the block object and then skip the block body by incrementing the bytePointer // to the block's bytecode' size. After that bytePointer will point to the place // right after the block's body. There we'll probably find the actual invoking code // such as sendMessage to a receiver (with our block as a parameter) or something similar. // Reading new byte pointer that points to the code right after the inline block uint16_t newBytePointer = byteCodes[ec.bytePointer] | (byteCodes[ec.bytePointer+1] << 8); // Skipping the newBytePointer's data ec.bytePointer += 2; // Creating block object hptr<TBlock> newBlock = newObject<TBlock>(); // Allocating block's stack uint32_t stackSize = getIntegerValue(ec.currentContext->method->stackSize); newBlock->stack = newObject<TObjectArray>(stackSize, false); newBlock->argumentLocation = newInteger(ec.instruction.low); newBlock->blockBytePointer = newInteger(ec.bytePointer); // Assigning creatingContext depending on the hierarchy // Nested blocks inherit the outer creating context if (ec.currentContext->getClass() == globals.blockClass) newBlock->creatingContext = ec.currentContext.cast<TBlock>()->creatingContext; else newBlock->creatingContext = ec.currentContext; // Inheriting the context objects newBlock->method = ec.currentContext->method; newBlock->arguments = ec.currentContext->arguments; newBlock->temporaries = ec.currentContext->temporaries; // Setting the execution point to a place right after the inlined block, // leaving the block object on top of the stack: ec.bytePointer = newBytePointer; stack[ec.stackTop++] = newBlock; }

case PushBlock: DBG0("PushBlock"); /* create a block object */ /* low is arg location */ /* next byte is goto value */ high = VAL; bytePointer += VALSIZE; rootStack[rootTop++] = context; op = rootStack[rootTop++] = gcalloc(x = integerValue(method->data[stackSizeInMethod])); op->class = ArrayClass; memoryClear(bytePtr(op), x * BytesPerWord); returnedValue = gcalloc(blockSize); returnedValue->class = BlockClass; returnedValue->data[bytePointerInContext] = returnedValue->data[stackTopInBlock] = returnedValue->data[previousContextInBlock] = NULL; returnedValue->data[bytePointerInBlock] = newInteger(bytePointer); returnedValue->data[argumentLocationInBlock] = newInteger(low); returnedValue->data[stackInBlock] = rootStack[--rootTop]; context = rootStack[--rootTop]; if(CLASS(context) == BlockClass) { returnedValue->data[creatingContextInBlock] = context->data[creatingContextInBlock]; } else { returnedValue->data[creatingContextInBlock] = context; } method = returnedValue->data[methodInBlock] = context->data[methodInBlock]; arguments = returnedValue->data[argumentsInBlock] = context->data[argumentsInBlock]; temporaries = returnedValue->data[temporariesInBlock] = context->data[temporariesInBlock]; stack = context->data[stackInContext]; bp = bytePtr(method->data[byteCodesInMethod]); stack->data[stackTop++] = returnedValue; /* zero these out just in case GC occurred */ literals = instanceVariables = 0; bytePointer = high; break;

Так было (форматирование и комментарии автора сохранены):

Переписать код Little Smalltalk на C++, устранить недостатки дизайна оригинала, откомментировать код, сделать его читаемым и легко модифицируемым. К сожалению, код оригинала был написан то ли индусами студентами, то ли кем-то еще. С моей точки зрения, учебному проекту (а именно так позиционировался Little Smalltalk автором) недопустимо иметь подобные исходники. Switch блоки на тыщу строк, посыпанные goto и макросами, переиспользование одной и той же переменной в пяти разных местах для разных целейЂЂЂ в общем, весело. Плюс, на весь код полтора комментария в стиле Ландавшица, вида: «из этого очевидно следуетЂЂЂ». Разумеется, так жить было нельзя. Поэтому код был проанализирован, и, в попытке понять Великий Замысел, появилась текущая реализация. Была разработана удобная система типов, шаблоны для контейнеров и шаблонные же указатели на объекты кучи, чтобы не приходилось думать о сборщике при каждом создании объекта. Теперь стало возможным из C++ работать с объектами виртуальной машины так же легко, как и с обычными структурами. Вся работа с памятью, расчет размеров объектов и их правильная инициализация теперь ложатся на плечи компилятора. В качестве примера приведу код реализации опкода номер 12 «PushBlock».

Цель ЂЂЂ1 Новая VM (Выполнено).

Мне всегда нравился Smalltalk. Своей клинической простотой (да простят меня лисперы и фортеры) и не менее клинически-широкими возможностями. Я считаю, что он незаслуженно забыт сообществом программистов, хотя в 21-м веке из него можно извлечь немало пользы. Однако, существующие промышленные реализации чересчур громоздки для первого знакомства и не блещут красотой своих форм. Встречают, как известно, по одежке. Новичок, впервые увидевший подобный интерфейс, вряд ли будет относиться к нему, как к чему-то современному и новаторскому. Little Smalltalk достаточно компактен, чтобы разобраться в нем за пару часов. В то же время это полноценный Smalltalk, хоть и не являющийся совместимым со стандартами Smalltalk-80 или ANSI-92. С моей точки зрения, грамотная реализация подобной микросистемы могла бы быть хорошим подспорьем в процессе обучения студентов технических ВУЗ-ов. Особенно полезен он в деле изучения ООП, поскольку концепции инкапсуляции, полиморфизма и наследования приобретают здесь совершенно четкое и в то же время очевидное выражение. Многие мои знакомые путались в этих понятиях или не понимали их изначального смысла. Имея же на руках подобный инструмент, можно за 10 минут показать буквально «на пальцах» преимущества ООП и механизмы его работы. Причем, в отличие от других языков, эти принципы не выглядят «притянутыми за уши», поскольку составляют фактическое ядро языка. В конце концов, довольно забавно иметь нечто, написанное фактически само на себе и в 150 КБ образа, умещающее компилятор и стандартную библиотеку с полным кодом всех своих методов. Особенно если это язык высокого уровня. Однако я заболтался, да и пост не совсем об этом. Поговорим лучше о проекте и его целях. Итак,

Всем привет! С прошедшим концом света и с наступающими праздниками В качестве подарка сообществу Open Source, а так же любителям антиквариата, мы (совместно с товарищем ) решили выложить нашу последнюю исследовательскую разработку. Предлагаем вашему вниманию с нуля переписанную на C++ реализацию виртуальной машины, совместимую с . На данный момент написан код виртуальной машины и реализованы базовые примитивы. Humbug написал серию простых тестов, которые, тем не менее, помогли обнаружить проблемы и в оригинальной версии VM. Реализация бинарно совместима с образами оригинального LST пятой версии. Месяц работы, 300+ коммитов. А что получилось в итоге, можно узнать под катом.

LLST: Новая жизнь Little Smalltalk | SavePearlHarbor

Комментариев нет:

Отправить комментарий