fix string handling
This commit is contained in:
		
							parent
							
								
									bb9e30a1c1
								
							
						
					
					
						commit
						6b7beadaeb
					
				| 
						 | 
				
			
			@ -31,7 +31,7 @@ OBJ_WASM = $(addprefix $(OBJ_DIR_WASM)/,$(notdir $(SRC:.c=.o)))
 | 
			
		|||
.PHONY: all clean install wasm
 | 
			
		||||
 | 
			
		||||
# Default target builds both versions
 | 
			
		||||
all: native wasm
 | 
			
		||||
all: native
 | 
			
		||||
 | 
			
		||||
# Native build rules
 | 
			
		||||
# ------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										85
									
								
								src/vm.c
								
								
								
								
							
							
						
						
									
										85
									
								
								src/vm.c
								
								
								
								
							| 
						 | 
				
			
			@ -28,32 +28,26 @@ uint32_t set_char(uint32_t word, int index, uint8_t ch) {
 | 
			
		|||
  return (word & ~(0xFF << (8 * index))) | (ch << (8 * index));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_memory_char(Data *memory, uint8_t ch, uint32_t buffer_addr,
 | 
			
		||||
                     uint32_t length) {
 | 
			
		||||
  uint32_t word = memory[buffer_addr + (length / 4)].u;
 | 
			
		||||
  word = set_char(word, length % 4, ch);
 | 
			
		||||
  memory[buffer_addr + (length / 4)].u = word;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Pack string into union-based memory */
 | 
			
		||||
void pack_string(Data *memory, const char *str, uint32_t length, uint32_t dest_addr) {
 | 
			
		||||
void pack_string(Data *memory, const char *str, uint32_t length,
 | 
			
		||||
                 uint32_t dest_addr) {
 | 
			
		||||
  memory[dest_addr].u = length;
 | 
			
		||||
  uint32_t buffer_addr = dest_addr + 1;
 | 
			
		||||
  int word_index = 0;
 | 
			
		||||
  int char_index = 0;
 | 
			
		||||
 | 
			
		||||
  uint32_t i = 0;
 | 
			
		||||
  while (i < length) {
 | 
			
		||||
    char ch = str[i++];
 | 
			
		||||
    char ch = str[i];
 | 
			
		||||
    if (ch == '\0') {
 | 
			
		||||
      uint32_t word = memory[buffer_addr + word_index].u;
 | 
			
		||||
      word = set_char(word, char_index, '\0');
 | 
			
		||||
      memory[buffer_addr + word_index].u = word;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t word = memory[buffer_addr + word_index].u;
 | 
			
		||||
    word = set_char(word, char_index, ch);
 | 
			
		||||
    memory[buffer_addr + word_index].u = word;
 | 
			
		||||
 | 
			
		||||
    char_index++;
 | 
			
		||||
    if (char_index == 4) {
 | 
			
		||||
      char_index = 0;
 | 
			
		||||
      word_index++;
 | 
			
		||||
    }
 | 
			
		||||
    set_memory_char(memory, ch, buffer_addr, i);
 | 
			
		||||
    i++;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,13 +105,11 @@ void run_vm(Data *memory, uint32_t memory_size) {
 | 
			
		|||
      memory[dest_addr].f = memory[src1_addr].f / memory[src2_addr].f;
 | 
			
		||||
      break;
 | 
			
		||||
    case OP_F32_TO_INT: {
 | 
			
		||||
      float tmp = memory[src1_addr].f;
 | 
			
		||||
      memory[dest_addr].u = (uint32_t)tmp;
 | 
			
		||||
      memory[dest_addr].u = (uint32_t)memory[src1_addr].f;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case OP_INT_TO_F32: {
 | 
			
		||||
      uint32_t tmp = memory[src1_addr].u;
 | 
			
		||||
      memory[dest_addr].f = (float)tmp;
 | 
			
		||||
      memory[dest_addr].f = (float)memory[src1_addr].u;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case OP_HALT:
 | 
			
		||||
| 
						 | 
				
			
			@ -155,43 +147,26 @@ void run_vm(Data *memory, uint32_t memory_size) {
 | 
			
		|||
      uint32_t string_addr = src1_addr;
 | 
			
		||||
      uint32_t length = memory[src1_addr - 1].u;
 | 
			
		||||
      uint32_t i;
 | 
			
		||||
      for (i = 0; i < length;) {
 | 
			
		||||
      for (i = 0; i < length; i++) {
 | 
			
		||||
        uint32_t word = memory[string_addr + (i / 4)].u;
 | 
			
		||||
        uint8_t ch = get_char(word, i % 4);
 | 
			
		||||
        if (ch == '\0')
 | 
			
		||||
          break;
 | 
			
		||||
        putchar(ch);
 | 
			
		||||
        i++;
 | 
			
		||||
      }
 | 
			
		||||
      putchar('\n');
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    case OP_READ_STRING: {
 | 
			
		||||
      putchar('>');
 | 
			
		||||
      putchar(' ');
 | 
			
		||||
      uint32_t buffer_addr = dest_addr + 1;
 | 
			
		||||
      uint32_t length = 0;
 | 
			
		||||
      int word_index = 0;
 | 
			
		||||
      int char_index = 0;
 | 
			
		||||
 | 
			
		||||
      while (1) {
 | 
			
		||||
        int ch = getchar();
 | 
			
		||||
        if (ch == '\n' || ch == EOF) {
 | 
			
		||||
          uint32_t word = memory[buffer_addr + word_index].u;
 | 
			
		||||
          word = set_char(word, char_index, '\0');
 | 
			
		||||
          memory[buffer_addr + word_index].u = word;
 | 
			
		||||
          set_memory_char(memory, '\0', buffer_addr, length);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uint32_t word = memory[buffer_addr + word_index].u;
 | 
			
		||||
        word = set_char(word, char_index, ch);
 | 
			
		||||
        memory[buffer_addr + word_index].u = word;
 | 
			
		||||
 | 
			
		||||
        char_index++;
 | 
			
		||||
        if (char_index == 4) {
 | 
			
		||||
          char_index = 0;
 | 
			
		||||
          word_index++;
 | 
			
		||||
        }
 | 
			
		||||
        set_memory_char(memory, ch, buffer_addr, length);
 | 
			
		||||
        length++;
 | 
			
		||||
      }
 | 
			
		||||
      memory[dest_addr].u = length;
 | 
			
		||||
| 
						 | 
				
			
			@ -201,20 +176,25 @@ void run_vm(Data *memory, uint32_t memory_size) {
 | 
			
		|||
      uint32_t addr1 = src1_addr;
 | 
			
		||||
      uint32_t addr2 = src2_addr;
 | 
			
		||||
      uint32_t length1 = memory[src1_addr - 1].u;
 | 
			
		||||
      uint32_t length2 = memory[src2_addr - 1].u;
 | 
			
		||||
      int equal = 1;
 | 
			
		||||
 | 
			
		||||
      uint32_t i;
 | 
			
		||||
      for (i = 0; i < length1;) {
 | 
			
		||||
        uint32_t word1 = memory[addr1 + i].u;
 | 
			
		||||
        uint32_t word2 = memory[addr2 + i].u;
 | 
			
		||||
        if (word1 != word2) {
 | 
			
		||||
          equal = 0;
 | 
			
		||||
          break;
 | 
			
		||||
      if (length1 != length2) {
 | 
			
		||||
        equal = 0;
 | 
			
		||||
      } else {
 | 
			
		||||
        uint32_t i = 0;
 | 
			
		||||
        while (i < length1) {
 | 
			
		||||
          uint32_t word1 = memory[addr1 + i].u;
 | 
			
		||||
          uint32_t word2 = memory[addr2 + i].u;
 | 
			
		||||
          if (word1 != word2) {
 | 
			
		||||
            equal = 0;
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          if ((word1 & 0xFF) == '\0' && (word2 & 0xFF) == '\0')
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if ((word1 & 0xFF) == '\0' && (word2 & 0xFF) == '\0')
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
      memory[dest_addr].u = equal; 
 | 
			
		||||
      memory[dest_addr].u = equal;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -223,4 +203,3 @@ void run_vm(Data *memory, uint32_t memory_size) {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue