Beispiel #1
0
bool VMTapeParser :: parseMessage(ident_t message, IdentifierString& reference)
{
   int paramCounter = 0;
   size_t length = getlength(message);
   length = message.find('[');
   if (length != NOTFOUND_POS) {
      reference.copy(message + length + 1);
      if (reference[reference.Length() - 1] == ']') {
         reference.truncate(reference.Length() - 1);
         //if (emptystr(reference)) {
         //   paramCounter = OPEN_ARG_COUNT;
         //}
         /*else */paramCounter = reference.ident().toInt();

      }
      else return false;
   }
   else return false;

   reference.clear();
   reference.append('0' + (char)paramCounter);
   reference.append(message, length);

   return true;
}
Beispiel #2
0
bool VMTapeParser :: writeExtension(TapeWriter& writer, ident_t message, int command)
{
   IdentifierString reference;

   size_t dotPos = message.find('.');
   if (parseMessage(message + dotPos + 1, reference)) {
      reference.insert(message, 0, dotPos + 1);

      writer.writeCommand(command, reference);

      return true;
   }
   else return false;
}
Beispiel #3
0
void parseMessageConstant(IdentifierString& message, ident_t reference)
{
   // message constant: nverb&signature

   int verbId = 0;
   int signatureId = 0;

   // read the param counter
   int count = reference[0] - '0';

   // skip the param counter
   reference+=1;

   int index = reference.find('&');
   //HOTFIX: for generic GET message we have to ignore ampresand
   if (reference[index + 1] == 0)
      index = -1;

   if (index != -1) {
      //HOTFIX: for GET message we have &&, so the second ampersand should be used
      if (reference[index + 1] == 0 || reference[index + 1] == '&')
         index++;

      IdentifierString verb(reference, index);
      ident_t signature = reference + index + 1;

      // if it is a predefined verb
      if (verb[0] == '#') {
         verbId = verb[1] - 0x20;
      }

      message.append(signature);
   }
   else {
      message.append(reference);
   }
}
Beispiel #4
0
void printMethod(_Module* module, ident_t methodReference, int pageSize)
{
   methodReference = trim(methodReference);

   int separator = methodReference.find('.');
   if (separator == -1) {
      printf("Invalid command");

      return;
   }

   IdentifierString className(methodReference, separator);

   ident_t methodName = methodReference + separator + 1;
   ref_t message = 0;

   // resolve method
   if (methodName[0] >= '0' && methodName[0] <= '9') {
      message = resolveMessageByIndex(module, className.ident(), methodName.toInt());
   }
   else message = resolveMessage(module, methodName);
   
   if (message == 0)
      return;

   // find class VMT
   _Memory* vmt = findClassVMT(module, className);
   _Memory* code = findClassCode(module, className);
   if (vmt == NULL || code == NULL) {
      printLine("Class not found: ", className);

      return;
   }

   // find method entry
   MemoryReader vmtReader(vmt);
   // read tape record size
   size_t size = vmtReader.getDWord();

   // read VMT header
   ClassHeader header;
   vmtReader.read((void*)&header, sizeof(ClassHeader));

   VMTEntry        entry;

   // read VMT while the entry not found
   size -= sizeof(ClassHeader);
   bool found = false;
   while (size > 0) {
      vmtReader.read((void*)&entry, sizeof(VMTEntry));

      if (entry.message == message) {
         found = true;

         IdentifierString temp;
         temp.copy(className);
         temp.append('.');
         printMessage(temp, module, entry.message);
         printLine("@method ", temp);

         printByteCodes(module, code, entry.address, 4, pageSize);
         print("@end\n");

         break;
      }

      size -= sizeof(VMTEntry);
   }
   if (!found) {
      printLine("Method not found:", methodName);
   }
}
Beispiel #5
0
ref_t resolveMessage(_Module* module, ident_t method)
{
   int paramCount = 0;
   ref_t actionRef = 0;
   ref_t flags = 0;

   if (method.startsWith("params#")) {
      flags |= VARIADIC_MESSAGE;

      method = method.c_str() + getlength("params#");
   }
   if (method.startsWith("prop#")) {
      flags |= PROPERTY_MESSAGE;

      method = method.c_str() + getlength("prop#");
   }
   if (method.startsWith("#invoke")) {
      flags |= SPECIAL_MESSAGE;
   }
   if (method.startsWith("#private&")) {
      flags |= STATIC_MESSAGE;

      method = method.c_str() + getlength("#private&");
   }
   if (method.compare("#init")) {
      flags |= SPECIAL_MESSAGE;
   }

   IdentifierString actionName;
   int paramIndex = method.find('[', -1);
   if (paramIndex != -1) {
      actionName.copy(method, paramIndex);

      IdentifierString countStr(method + paramIndex + 1, getlength(method) - paramIndex - 2);
      paramCount = countStr.ident().toInt();
   }
   else actionName.copy(method);

   //if (actionName.compare("dispatch")) {
   //   actionRef = DISPATCH_MESSAGE_ID;
   //}
   //else if (actionName.compare("#new")) {
   //   actionRef = NEWOBJECT_MESSAGE_ID;
   //}
   ///*else */if (actionName.compare("#init")) {
   //   actionRef = INIT_MESSAGE_ID;
   //}
   //else {
   //   if (method.find("set&") != NOTFOUND_POS) {
   //      actionName.cut(0, 4);
   //      flags = PROPSET_MESSAGE;
   //   }
   //   else if (method.startsWith("#cast<") && paramCount > 0) {
   //      flags = SPECIAL_MESSAGE;
   //   }
   ////   else if (actionName.compare("set")) {
   ////      flags = PROPSET_MESSAGE;
   ////   }

      ref_t signature = 0;
      size_t index = actionName.ident().find('<');
      if (index != NOTFOUND_POS) {
         ref_t references[ARG_COUNT];
         size_t end = actionName.ident().find('>');
         size_t len = 0;
         size_t i = index + 1;
         while (i < end) {
            size_t j = actionName.ident().find(i, ',', end);

            IdentifierString temp(actionName.c_str() + i, j-i);
            references[len++] = module->mapReference(temp, true);

            i = j + 1;
         }

         signature = module->mapSignature(references, len, true);

         actionName.truncate(index);
      }

      actionRef = module->mapAction(actionName, signature, true);
      if (actionRef == 0) {
         printLine("Unknown subject ", actionName);

         return 0;
      }
   //}

   return encodeMessage(actionRef, paramCount, flags);
}