experiments/little-smalltalk/run.cc
author Tony Garnock-Jones <tonygarnockjones@gmail.com>
Sun, 05 Aug 2018 20:06:00 +0100
changeset 435 8cad65af7913
parent 434 5c04878ec48e
child 436 f519b01f759b
permissions -rw-r--r--
Shrink the default/initial heap a bit so it doesn't overwhelm smaller machines
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     1
#include <cstring>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     2
#include <cstdio>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     3
#include <cstdlib>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     4
#include <cstdint>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     5
#include <ctime>
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
     6
#include <cassert>
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     7
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     8
#include <string>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
     9
#include <iostream>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    10
#include <iomanip>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    11
#include <fstream>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    12
#include <vector>
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    13
#include <deque>
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    14
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    15
#include <netinet/in.h>
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    16
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    17
using namespace std;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    18
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    19
typedef void *obj;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    20
typedef intptr_t smi;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    21
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    22
static inline int isSmi(obj o) { return ((intptr_t) o) & 1; }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    23
static inline obj mkSmi(intptr_t v) { return (obj) ((v << 1) | 1); }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    24
static inline smi unSmi(obj o) { return ((smi) o) >> 1; }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    25
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    26
static inline intptr_t objHeader(obj o) { return ((intptr_t *) o)[0]; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    27
static inline int isUnused(obj o) { return objHeader(o) == 0; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    28
static inline int isMarked(obj o) { return objHeader(o) & 1; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    29
static inline int isBytes(obj o) { return objHeader(o) & 2; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    30
static inline unsigned slotCount(obj o) { return (objHeader(o) >> 2) - 1; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    31
static inline unsigned bytesCount(obj o) { return (objHeader(o) >> 2) - 1; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    32
static inline void mark(obj o) { ((intptr_t *) o)[0] |= 1; }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    33
static inline void unmark(obj o) { ((intptr_t *) o)[0] &= ~((intptr_t) 1); }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    34
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    35
static inline obj *classAddr(obj o) { return &(((obj *) o)[1]); }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    36
static inline obj *slotAddr(obj o, unsigned i) { return &(((obj *) o)[i + 2]); }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    37
static inline obj slotAt(obj o, unsigned i) { return *slotAddr(o, i); }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    38
static inline void slotAtPut(obj o, unsigned i, obj v) { *slotAddr(o, i) = v; }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    39
static inline uint8_t *bvBytes(obj o) { return (uint8_t *) &(((obj *) o)[2]); }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    40
static inline string bvString(obj o) { return string((char *) bvBytes(o), bytesCount(o)); }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    41
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    42
static inline intptr_t objHeader(unsigned count, int isBs) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    43
  return (((intptr_t) count + 1) << 2) | (isBs ? 2 : 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    44
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    45
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    46
static inline intptr_t freeHeader(unsigned blockWords) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    47
  assert(blockWords >= 2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    48
  return objHeader(blockWords - 2, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    49
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    50
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    51
static inline unsigned roundUpAllocation(unsigned nBytes) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    52
  return (nBytes + sizeof(obj) - 1) & ~(sizeof(obj) - 1);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    53
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    54
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    55
static inline void _fillWith(obj o, unsigned n, obj v) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    56
  fill(slotAddr(o, 0), slotAddr(o, n), v);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    57
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    58
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    59
static int32_t nextInt(istream &f) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    60
  int32_t i;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    61
  f.read((char *) &i, sizeof(int32_t));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    62
  return ntohl(i);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    63
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    64
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    65
static long operator-(struct timespec const &a, struct timespec const &b) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    66
  long delta = (a.tv_sec - b.tv_sec) * 1000000;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    67
  return delta + ((a.tv_nsec - b.tv_nsec) / 1000);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    68
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    69
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    70
struct VM;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    71
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    72
struct Root {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    73
  VM *vm;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    74
  obj *ptr;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    75
  Root *next;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    76
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    77
  Root(VM *vm, obj *ptr);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    78
  ~Root();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    79
};
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    80
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    81
typedef obj (*primitive_handler_t)(unsigned, VM &, obj);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    82
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    83
static obj unhandledPrimitive(unsigned, VM &, obj);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    84
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    85
struct VM {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    86
  int gcEnabled;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
    87
  vector<obj> heap;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    88
  obj *allocPtr;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    89
  obj *allocLimit;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    90
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    91
  obj _nil;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    92
  obj _true;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    93
  obj _false;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    94
  obj _Array;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    95
  obj _Block;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    96
  obj _Context;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    97
  obj _Integer;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
    98
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
    99
  obj _activeCtx;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   100
  obj _i;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   101
  obj _j;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   102
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   103
  obj __method;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   104
  obj __args;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   105
  obj __temps;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   106
  obj __stack;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   107
  obj __prevCtx;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   108
  obj __receiver;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   109
  obj __literals;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   110
  unsigned __ip;
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   111
  unsigned __stackTop;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   112
  uint8_t *__bytecode;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   113
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   114
  Root *rootStack;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   115
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   116
  primitive_handler_t primitiveTable[256];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   117
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   118
  struct timespec mutatorStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   119
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   120
  inline obj objClass(obj o) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   121
    return isSmi(o) ? _Integer : *classAddr(o);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   122
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   123
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   124
  string className(obj c) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   125
    if (c == _nil) return "(nil)";
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   126
    return bvString(slotAt(c, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   127
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   128
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   129
  string objClassName(obj o) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   130
    return className(objClass(o));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   131
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   132
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   133
  VM() {
435
8cad65af7913 Shrink the default/initial heap a bit so it doesn't overwhelm smaller machines
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 434
diff changeset
   134
    unsigned heapSize = 8 * 1048576;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   135
    heap.resize(heapSize, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   136
    cerr << "Heap bounds: " << &heap[0] << "-" << &heap[heapSize] << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   137
    allocPtr = &heap[0];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   138
    *allocPtr = (obj) freeHeader(heapSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   139
    allocLimit = allocPtr + heapSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   140
    gcEnabled = 0; // during image loading
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   141
    fill(&primitiveTable[0], &primitiveTable[256], unhandledPrimitive);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   142
    rootStack = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   143
    new Root(this, &_nil);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   144
    new Root(this, &_true);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   145
    new Root(this, &_false);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   146
    new Root(this, &_Array);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   147
    new Root(this, &_Block);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   148
    new Root(this, &_Context);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   149
    new Root(this, &_Integer);
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   150
    new Root(this, &_activeCtx);
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   151
    new Root(this, &_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   152
    new Root(this, &_j);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   153
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   154
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   155
  void scheduleMark(deque<obj *> &q, obj *p) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   156
    // cerr << "  scheduling mark of " << p << " (" << *p << ")" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   157
    q.push_back(p);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   158
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   159
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   160
  void gc() {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   161
    struct timespec gcStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   162
    clock_gettime(CLOCK_MONOTONIC, &gcStart);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   163
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   164
    unsigned liveCount = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   165
    unsigned scanCount = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   166
    unsigned byteCount = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   167
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   168
    deque<obj *> q;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   169
    // cerr << "VM this = " << this << "-" << (this + 1) << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   170
    for (Root *r = rootStack; r != 0; r = r->next) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   171
      scheduleMark(q, r->ptr);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   172
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   173
    while (!q.empty()) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   174
      obj *op = q.front();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   175
      q.pop_front();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   176
      scanCount++;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   177
      // cerr << "Scan of " << op;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   178
      obj o = *op;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   179
      // cerr << " (" << o << ")" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   180
      if (isSmi(o)) continue;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   181
      if (isMarked(o)) continue;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   182
      // cerr << "Marking " << o << " which is "; print(cerr, o); cerr << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   183
      mark(o);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   184
      liveCount++;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   185
      scheduleMark(q, classAddr(o));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   186
      if (!isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   187
        for (int i = 0; i < slotCount(o); i++) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   188
          scheduleMark(q, slotAddr(o, i));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   189
        }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   190
      } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   191
        byteCount += bytesCount(o);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   192
      }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   193
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   194
    // {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   195
    //   obj *p = &heap[0];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   196
    //   cerr << "-------------- allocBase == " << &heap[0] << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   197
    //   while (p < allocLimit) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   198
    //     obj o = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   199
    //     cerr << o << (isUnused(o) ? " (unused)" :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   200
    //                   isMarked(o) ? " (marked) " :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   201
    //                   " (      ) ");
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   202
    //     if (isUnused(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   203
    //       p++;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   204
    //     } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   205
    //       if (isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   206
    //         cerr << bytesCount(o) << " bytes";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   207
    //       } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   208
    //         cerr << slotCount(o) << " slots";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   209
    //       }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   210
    //       p += objSize(p);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   211
    //       if (!isMarked(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   212
    //         // TODO remove
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   213
    //         uint8_t *stomple = ((uint8_t *) o) + sizeof(obj);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   214
    //         unsigned stompcount = ((uint8_t *) p) - stomple;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   215
    //         cerr << " (stomping on " << stompcount << " bytes)";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   216
    //         memset(stomple, 0x5a, stompcount);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   217
    //       }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   218
    //     }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   219
    //     cerr << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   220
    //   }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   221
    //   cerr << "-------------- end of sweep" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   222
    // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   223
    allocPtr = &heap[0];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   224
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   225
    struct timespec gcEnd;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   226
    clock_gettime(CLOCK_MONOTONIC, &gcEnd);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   227
    long gc_us = gcEnd - gcStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   228
    long mutator_us = gcStart - mutatorStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   229
    double mutator_percentage = (100.0 * mutator_us) / (mutator_us + gc_us);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   230
    cerr << " complete in " << gc_us << "??s."
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   231
         << " Mutator ran for " << mutator_us << "??s (" << mutator_percentage << "%)."
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   232
         << " " << liveCount << " live objects; "
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   233
         << scanCount << " words scanned, "
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   234
         << byteCount << " bytes skipped."
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   235
         << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   236
    mutatorStart = gcEnd;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   237
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   238
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   239
  unsigned objSize(obj o) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   240
    if (isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   241
      return (roundUpAllocation(bytesCount(o)) / sizeof(obj)) + 2;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   242
    } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   243
      return slotCount(o) + 2;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   244
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   245
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   246
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   247
  unsigned chunkSizeAt(obj *p) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   248
    obj o = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   249
    return
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   250
      isUnused(o) ? 1 :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   251
      isMarked(o) ? 0 :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   252
      objSize(o);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   253
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   254
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   255
  void findFree(unsigned nObj, obj *&candidate, unsigned &candidateSize) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   256
    candidate = allocPtr;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   257
    // cerr << "Hunting for " << nObj << " words at " << candidate << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   258
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   259
  restart:
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   260
    obj *scan = candidate;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   261
    candidateSize = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   262
    while ((candidateSize < nObj) && (scan < allocLimit)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   263
      unsigned nextChunkSize = chunkSizeAt(scan);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   264
      if (nextChunkSize == 0) { // marked block - not at allocLimit by loop condition
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   265
        unmark((obj) scan);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   266
        candidate = scan + objSize(scan);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   267
        goto restart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   268
      }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   269
      candidateSize += nextChunkSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   270
      // cerr << "  after nextChunkSize==" << nextChunkSize
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   271
      //      << " at " << scan << "-" << (scan + nextChunkSize)
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   272
      //      << ", candidateSize==" << candidateSize << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   273
      scan += nextChunkSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   274
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   275
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   276
    // cerr << "  Final candidateSize: " << candidateSize << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   277
    if (candidateSize < nObj) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   278
      candidate = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   279
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   280
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   281
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   282
  // void growHeap() {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   283
  //   // BOGUS: resizing likely moves the base pointer, forcing rewrite
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   284
  //   // of all live pointers. We could in principle do this, but it'd
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   285
  //   // be more convenient to choose our moment so that, say, we have a
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   286
  //   // guarantee that only the pointers in the root set are live.
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   287
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   288
  //   unsigned oldSize = heap.size();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   289
  //   unsigned newSize = oldSize * 2;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   290
  //   cerr << "Growing heap from " << oldSize << " words to " << newSize << " words" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   291
  //   heap.resize(newSize, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   292
  //   cerr << "Heap bounds: " << &heap[0] << "-" << &heap[newSize] << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   293
  //   allocPtr = &heap[oldSize];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   294
  //   *allocPtr = (obj) freeHeader(newSize - oldSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   295
  //   allocLimit = allocPtr + newSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   296
  // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   297
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   298
  obj *allocBlock(unsigned nObj) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   299
    obj *candidate = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   300
    unsigned candidateSize = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   301
    findFree(nObj, candidate, candidateSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   302
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   303
    if (candidate == 0) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   304
      if (gcEnabled) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   305
        cerr << "gc()...";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   306
        storeRegisters();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   307
        gc();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   308
        findFree(nObj, candidate, candidateSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   309
      }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   310
      if (candidate == 0) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   311
        cerr << "Out of memory, heap resizing not yet implemented" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   312
        exit(1);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   313
      }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   314
      // while (candidate == 0) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   315
      //   growHeap();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   316
      //   findFree(nObj, candidate, candidateSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   317
      // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   318
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   319
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   320
    // cerr << "  candidate==" << candidate
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   321
    //      << ", candidateSize==" << candidateSize
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   322
    //      << ", nObj+2==" << (nObj + 2)
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   323
    //      << ", possibleLeftoverInclHeader==" << (candidateSize - nObj)
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   324
    //      << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   325
    assert(candidateSize >= nObj);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   326
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   327
    if (candidateSize > (nObj + 2)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   328
      allocPtr = candidate + nObj;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   329
      *allocPtr = (obj) freeHeader(candidateSize - nObj);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   330
    } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   331
      fill(candidate + nObj, candidate + candidateSize, (obj) 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   332
      allocPtr = candidate + candidateSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   333
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   334
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   335
    // if (allocPtr == allocLimit) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   336
    //   cerr << "Next allocation will GC!" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   337
    // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   338
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   339
    return candidate;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   340
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   341
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   342
  obj allocObj(unsigned nSlots, obj klass) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   343
    obj *p = allocBlock(nSlots + 2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   344
    obj result = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   345
    *p++ = (obj) objHeader(nSlots, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   346
    *p++ = klass;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   347
    fill(p, p + nSlots, _nil);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   348
    return result;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   349
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   350
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   351
  obj allocBytes(unsigned nBytes, obj klass) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   352
    obj *p = allocBlock((roundUpAllocation(nBytes) / sizeof(obj)) + 2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   353
    obj result = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   354
    *p++ = (obj) objHeader(nBytes, 1);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   355
    *p++ = klass;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   356
    return result;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   357
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   358
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   359
  obj allocBytes(string const &s, obj klass) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   360
    obj o = allocBytes(s.length(), klass);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   361
    memcpy(bvBytes(o), s.c_str(), s.length());
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   362
    return o;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   363
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   364
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   365
  obj allocRawArray(unsigned n) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   366
    return allocObj(n, _Array);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   367
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   368
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   369
  obj allocArray(unsigned n, obj v) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   370
    obj o = allocRawArray(n);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   371
    _fillWith(o, n, v);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   372
    return o;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   373
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   374
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   375
  obj allocArray(unsigned n) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   376
    return allocArray(n, _nil);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   377
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   378
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   379
  void print(ostream &f, obj o) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   380
    if (isSmi(o)) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   381
      f << unSmi(o);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   382
      return;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   383
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   384
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   385
    string className = objClassName(o);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   386
    int isString = className.compare("String") == 0;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   387
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   388
    if (!isString) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   389
      f << className;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   390
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   391
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   392
    if (isBytes(o)) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   393
      f << (isString ? '\"' : '{');
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   394
      ios_base::fmtflags saved(f.flags());
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   395
      char fill = f.fill('0');
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   396
      f << hex;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   397
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   398
      for (int i = 0; i < bytesCount(o); i++) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   399
        char c = bvBytes(o)[i];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   400
        if (isString) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   401
          switch (c) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   402
            case '\"': f << "\\\""; break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   403
            case '\n': f << "\\n"; break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   404
            default: f << c; break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   405
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   406
        } else {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   407
          f << setw(2) << ((unsigned) c & 0xff);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   408
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   409
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   410
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   411
      f.flags(saved);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   412
      f.fill(fill);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   413
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   414
      f << (isString ? '\"' : '}');
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   415
    } else {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   416
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   417
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   418
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   419
  int loadImage(string const &filename) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   420
    ifstream f(filename);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   421
    vector<obj> table;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   422
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   423
    if (!f.is_open()) return 0;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   424
    if (nextInt(f) != 1 || !f) return 0; // wrong image version
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   425
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   426
    while (true) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   427
      int32_t len = nextInt(f);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   428
      if (!f) break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   429
      int32_t code = nextInt(f);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   430
      int32_t classIndex = nextInt(f);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   431
      int32_t oopCount = nextInt(f);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   432
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   433
      switch (code) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   434
        case 0:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   435
          if (len != 5) return 0; // weird SmallInt object length
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   436
          if (oopCount != 0) return 0; // SmallInt doesn't get to have slots
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   437
          table.push_back(mkSmi(nextInt(f)));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   438
          break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   439
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   440
        case 1: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   441
          int32_t byteCount = len - oopCount - 4;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   442
          obj bv = allocBytes(byteCount, mkSmi(classIndex));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   443
          f.read((char *) bvBytes(bv), byteCount);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   444
          table.push_back(bv);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   445
          break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   446
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   447
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   448
        case 2: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   449
          obj o = allocObj(oopCount, mkSmi(classIndex));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   450
          for (int i = 0; i < oopCount; i++) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   451
            slotAtPut(o, i, mkSmi(nextInt(f)));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   452
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   453
          table.push_back(o);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   454
          break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   455
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   456
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   457
        default:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   458
          return 0; // unhandled code
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   459
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   460
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   461
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   462
    cerr << "Loading: starting fixup" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   463
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   464
    for (vector<obj>::iterator it = table.begin(); it != table.end(); ++it) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   465
      obj o = *it;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   466
      if (!isSmi(o)) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   467
        *classAddr(o) = table[unSmi(*classAddr(o))];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   468
        if (!isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   469
          for (unsigned i = 0; i < slotCount(o); i++) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   470
            *slotAddr(o, i) = table[unSmi(*slotAddr(o, i))];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   471
          }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   472
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   473
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   474
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   475
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   476
    cerr << "Loading: fixup complete" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   477
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   478
    _i = _j = _nil = table[0];
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   479
    _true = table[1];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   480
    _false = table[2];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   481
    _Array = table[3];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   482
    _Block = table[4];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   483
    _Context = table[5];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   484
    _Integer = table[6];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   485
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   486
    return 1;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   487
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   488
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   489
  obj searchClassMethodDictionary(obj c, obj selector) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   490
    obj methods = slotAt(c, 2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   491
    unsigned selectorLen = bytesCount(selector);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   492
    char const *selectorBytes = (char const *) bvBytes(selector);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   493
    for (unsigned i = 0; i < slotCount(methods); i++) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   494
      obj m = slotAt(methods, i);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   495
      obj mname = slotAt(m, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   496
      // cerr << "  " << selectorBytes << " =?= " << bvString(mname) << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   497
      if ((bytesCount(mname) == selectorLen) &&
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   498
          (memcmp(bvBytes(mname), selectorBytes, selectorLen) == 0)) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   499
        return m;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   500
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   501
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   502
    return 0;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   503
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   504
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   505
  void callMethod_i_j() {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   506
    unsigned tempCount = (unsigned) unSmi(slotAt(_j, 4));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   507
    unsigned maxStack = (unsigned) unSmi(slotAt(_j, 3));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   508
    {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   509
      obj ctx = allocObj(7, _Context);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   510
      slotAtPut(ctx, 0, _j); // method
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   511
      slotAtPut(ctx, 1, _i); // args
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   512
      _i = ctx;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   513
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   514
    slotAtPut(_i, 2, allocArray(tempCount));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   515
    slotAtPut(_i, 3, allocArray(maxStack));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   516
    slotAtPut(_i, 4, mkSmi(0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   517
    slotAtPut(_i, 5, mkSmi(0));
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   518
    slotAtPut(_i, 6, _activeCtx);
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   519
    loadContext(_i);
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   520
    _i = _j = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   521
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   522
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   523
  void push(obj v) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   524
    slotAtPut(__stack, __stackTop++, v);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   525
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   526
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   527
  obj pop() {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   528
    return slotAt(__stack, --__stackTop);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   529
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   530
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   531
  obj peek() {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   532
    return slotAt(__stack, __stackTop - 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   533
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   534
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   535
  uint8_t nextByte() {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   536
    return __bytecode[__ip++];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   537
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   538
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   539
  void popArray_i(uint8_t count) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   540
    _i = allocRawArray(count);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   541
    __stackTop -= count;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   542
    copy(slotAddr(__stack, __stackTop), slotAddr(__stack, __stackTop + count), slotAddr(_i, 0));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   543
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   544
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   545
  void loadContext(obj ctx);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   546
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   547
  void loadContextAndPush(obj ctx, obj v) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   548
    loadContext(ctx);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   549
    push(v);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   550
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   551
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   552
  void storeRegisters() {
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   553
    slotAtPut(_activeCtx, 4, mkSmi(__ip));
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   554
    slotAtPut(_activeCtx, 5, mkSmi(__stackTop));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   555
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   556
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   557
  obj lookupMethod(obj c, obj selector) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   558
    while (c != _nil) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   559
      // cerr << "Searching in " << className(c) << " for "; print(cerr, selector); cerr << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   560
      obj m = searchClassMethodDictionary(c, selector);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   561
      if (m != 0) return m;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   562
      c = slotAt(c, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   563
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   564
    return 0;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   565
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   566
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   567
  void sendMessage_i_j(obj c) {
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   568
    storeRegisters();
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   569
    // cerr << "Sending " << bvString(_j) << " via " << className(c) << " to ";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   570
    // print(cerr, slotAt(_i, 0));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   571
    // cerr << endl;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   572
    obj method = lookupMethod(c, _j);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   573
    if (method == 0) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   574
      cerr << "DNU ";
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   575
      print(cerr, slotAt(_i, 0));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   576
      cerr << ' ';
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   577
      print(cerr, _j);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   578
      cerr << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   579
      exit(2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   580
    }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   581
    _j = method;
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   582
    callMethod_i_j();
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   583
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   584
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   585
  void interpret() {
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   586
    while (_activeCtx != _nil) {
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   587
      uint8_t opcode, arg;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   588
      opcode = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   589
      arg = opcode & 0xf;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   590
      opcode = opcode >> 4;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   591
      if (opcode == 0) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   592
        opcode = arg;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   593
        arg = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   594
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   595
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   596
      // cerr << (int) opcode << ' ' << (int) arg;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   597
      // for (int i = 0; i < __stackTop; i++) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   598
      //   cerr << ' ';
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   599
      //   print(cerr, slotAt(__stack, i));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   600
      // }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   601
      // cerr << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   602
      // cerr << flush;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   603
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   604
      switch (opcode) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   605
        case 1: push(slotAt(__receiver, arg)); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   606
        case 2: push(slotAt(__args, arg)); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   607
        case 3: push(slotAt(__temps, arg)); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   608
        case 4: push(slotAt(__literals, arg)); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   609
        case 5:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   610
          if (arg < 10) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   611
            push(mkSmi(arg));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   612
          } else {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   613
            switch (arg) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   614
              case 10: push(_nil); break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   615
              case 11: push(_true); break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   616
              case 12: push(_false); break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   617
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   618
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   619
          continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   620
        case 6: slotAtPut(__receiver, arg, peek()); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   621
        case 7: slotAtPut(__temps, arg, peek()); continue;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   622
        case 8: {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   623
          popArray_i(arg);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   624
          push(_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   625
          _i = _nil;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   626
          continue;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   627
        }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   628
        case 9: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   629
          _i = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   630
          _j = slotAt(__literals, arg);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   631
          sendMessage_i_j(objClass(slotAt(_i, 0)));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   632
          continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   633
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   634
        case 10:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   635
          switch (arg) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   636
            case 0: push((pop() == _nil) ? _true : _false); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   637
            case 1: push((pop() != _nil) ? _true : _false); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   638
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   639
        case 11: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   640
          _j = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   641
          _i = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   642
          if (isSmi(_i) && isSmi(_j)) {
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   643
            switch (arg) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   644
              case 0: push((unSmi(_i) < unSmi(_j)) ? _true : _false); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   645
              case 1: push((unSmi(_i) <= unSmi(_j)) ? _true : _false); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   646
              case 2: push(mkSmi(unSmi(_i) + unSmi(_j))); break;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   647
            }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   648
            _i = _j = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   649
          } else {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   650
            {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   651
              obj newArgs = allocRawArray(2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   652
              slotAtPut(newArgs, 0, _i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   653
              slotAtPut(newArgs, 1, _j);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   654
              _i = newArgs;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   655
            }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   656
            switch (arg) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   657
              case 0: _j = allocBytes("<", _nil); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   658
              case 1: _j = allocBytes("<=", _nil); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   659
              case 2: _j = allocBytes("+", _nil); break;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   660
            }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   661
            sendMessage_i_j(objClass(slotAt(_i, 0)));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   662
          }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   663
          continue;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   664
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   665
        case 12: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   666
          uint8_t target = nextByte();
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   667
          _i = allocObj(10, _Block);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   668
          slotAtPut(_i, 0, __method);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   669
          slotAtPut(_i, 1, __args);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   670
          slotAtPut(_i, 2, __temps);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   671
          slotAtPut(_i, 3, __stack);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   672
          slotAtPut(_i, 4, mkSmi(__ip));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   673
          slotAtPut(_i, 5, mkSmi(0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   674
          slotAtPut(_i, 6, __prevCtx);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   675
          slotAtPut(_i, 7, mkSmi(arg));
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   676
          slotAtPut(_i, 8, _activeCtx);
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   677
          slotAtPut(_i, 9, mkSmi(__ip));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   678
          push(_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   679
          _i = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   680
          __ip = target;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   681
          continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   682
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   683
        case 13: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   684
          uint8_t primNumber = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   685
          // cerr << "  primNumber = " << (int) primNumber << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   686
          switch (primNumber) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   687
            case 6: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   688
              loadContext(pop());
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   689
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   690
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   691
            case 8: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   692
              _j = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   693
              unsigned argloc = unSmi(slotAt(_j, 7));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   694
              unsigned argcount = arg - 1;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   695
              copy(slotAddr(__stack, __stackTop - argcount),
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   696
                   slotAddr(__stack, __stackTop),
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   697
                   slotAddr(slotAt(_j, 2), argloc));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   698
              __stackTop = __stackTop - argcount;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   699
              storeRegisters();
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   700
              _i = allocObj(10, _Block);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   701
              slotAtPut(_i, 0, slotAt(_j, 0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   702
              slotAtPut(_i, 1, slotAt(_j, 1));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   703
              slotAtPut(_i, 2, slotAt(_j, 2));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   704
              slotAtPut(_i, 3, allocArray(slotCount(slotAt(_j, 3))));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   705
              slotAtPut(_i, 4, slotAt(_j, 9));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   706
              slotAtPut(_i, 5, mkSmi(0));
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   707
              slotAtPut(_i, 6, slotAt(_activeCtx, 6));
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   708
              slotAtPut(_i, 7, slotAt(_j, 7));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   709
              slotAtPut(_i, 8, slotAt(_j, 8));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   710
              slotAtPut(_i, 9, slotAt(_j, 9));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   711
              loadContext(_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   712
              _i = _j = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   713
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   714
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   715
            case 34: return;
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   716
            case 35: push(_activeCtx); continue;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   717
            default:
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   718
              popArray_i(arg);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   719
              push(primitiveTable[primNumber](primNumber, *this, _i));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   720
              _i = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   721
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   722
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   723
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   724
        case 14: push(slotAt(objClass(__receiver), arg + 5)); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   725
        case 15:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   726
          switch (arg) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   727
            case 1: loadContextAndPush(__prevCtx, __receiver); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   728
            case 2: loadContextAndPush(__prevCtx, pop()); continue;
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   729
            case 3: loadContextAndPush(slotAt(slotAt(_activeCtx, 8), 6), pop()); continue;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   730
            case 4: push(peek()); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   731
            case 5: pop(); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   732
            case 6: __ip = nextByte(); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   733
            case 7: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   734
              unsigned target = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   735
              if (pop() == _true) __ip = target;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   736
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   737
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   738
            case 8: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   739
              unsigned target = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   740
              if (pop() == _false) __ip = target;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   741
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   742
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   743
            case 11: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   744
              _i = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   745
              _j = slotAt(__literals, nextByte());
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   746
              sendMessage_i_j(slotAt(slotAt(__method, 5), 1));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   747
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   748
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   749
            default:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   750
              cerr << "Unhandled opcode 15 arg " << (int) arg << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   751
              exit(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   752
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   753
        default:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   754
          cerr << "Unhandled opcode " << (int) opcode << ", " << (int) arg << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   755
          exit(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   756
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   757
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   758
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   759
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   760
  void installPrimitive(unsigned primNumber, primitive_handler_t handler) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   761
    primitiveTable[primNumber] = handler;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   762
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   763
};
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   764
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   765
void VM::loadContext(obj ctx) {
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   766
  _activeCtx = ctx;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   767
  if (ctx != _nil) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   768
    __method = slotAt(ctx, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   769
    __args = slotAt(ctx, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   770
    __temps = slotAt(ctx, 2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   771
    __stack = slotAt(ctx, 3);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   772
    __ip = unSmi(slotAt(ctx, 4));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   773
    __stackTop = unSmi(slotAt(ctx, 5));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   774
    __prevCtx = slotAt(ctx, 6);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   775
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   776
    __receiver = slotAt(__args, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   777
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   778
    __bytecode = bvBytes(slotAt(__method, 1));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   779
    __literals = slotAt(__method, 2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   780
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   781
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   782
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   783
Root::Root(VM *vm, obj *ptr) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   784
  this->vm = vm;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   785
  this->ptr = ptr;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   786
  this->next = vm->rootStack;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   787
  vm->rootStack = this;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   788
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   789
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   790
Root::~Root() {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   791
  if (vm->rootStack != this) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   792
    cerr << "Root stack corruption" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   793
    exit(1);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   794
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   795
  vm->rootStack = next;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   796
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   797
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   798
static obj unhandledPrimitive(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   799
  cerr << "Primitive " << primNumber << " is unhandled" << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   800
  exit(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   801
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   802
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   803
static obj prim_eq(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   804
  return (slotAt(args, 0) == slotAt(args, 1)) ? vm._true : vm._false;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   805
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   806
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   807
static obj prim_getClass(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   808
  return vm.objClass(slotAt(args, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   809
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   810
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   811
static obj prim_objectSize(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   812
  obj o = slotAt(args, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   813
  if (isSmi(o)) return mkSmi(0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   814
  if (isBytes(o)) return mkSmi(bytesCount(o));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   815
  return mkSmi(slotCount(o));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   816
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   817
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   818
static obj prim_slotAtPut(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   819
  slotAtPut(slotAt(args, 1), unSmi(slotAt(args, 2)) - 1, slotAt(args, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   820
  return slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   821
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   822
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   823
static obj prim_mkObject(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   824
  obj r = vm.allocObj(unSmi(slotAt(args, 1)), slotAt(args, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   825
  _fillWith(r, slotCount(r), vm._nil);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   826
  return r;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   827
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   828
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   829
static obj prim_numericQuotient(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   830
  return mkSmi(unSmi(slotAt(args, 0)) / unSmi(slotAt(args, 1)));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   831
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   832
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   833
static obj prim_numericModulo(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   834
  return mkSmi(unSmi(slotAt(args, 0)) % unSmi(slotAt(args, 1)));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   835
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   836
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   837
static obj prim_numericEq(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   838
  return (slotAt(args, 0) == slotAt(args, 1)) ? vm._true : vm._false;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   839
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   840
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   841
static obj prim_numericSub(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   842
  return mkSmi(unSmi(slotAt(args, 0)) - unSmi(slotAt(args, 1)));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   843
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   844
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   845
static obj prim_numericMul(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   846
  // TODO overflow checks
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   847
  return mkSmi(unSmi(slotAt(args, 0)) * unSmi(slotAt(args, 1)));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   848
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   849
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   850
static obj prim_mkBytes(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   851
  return vm.allocBytes(unSmi(slotAt(args, 1)), slotAt(args, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   852
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   853
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   854
static obj prim_bytesRef(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   855
  return mkSmi(bvBytes(slotAt(args, 0))[unSmi(slotAt(args, 1)) - 1]);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   856
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   857
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   858
static obj prim_bytesSet(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   859
  bvBytes(slotAt(args, 1))[unSmi(slotAt(args, 2)) - 1] = unSmi(slotAt(args, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   860
  return slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   861
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   862
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   863
static obj prim_bytesAppend(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   864
  obj b = slotAt(args, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   865
  obj a = slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   866
  obj r = vm.allocBytes(bytesCount(a) + bytesCount(b), vm.objClass(a));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   867
  memcpy(bvBytes(r), bvBytes(a), bytesCount(a));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   868
  memcpy(bvBytes(r) + bytesCount(a), bvBytes(b), bytesCount(b));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   869
  return r;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   870
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   871
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   872
static obj prim_bytesCmp(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   873
  obj a = slotAt(args, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   874
  obj b = slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   875
  int alen = bytesCount(a);
432
527bdc1042a9 Typo fix
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 431
diff changeset
   876
  int blen = bytesCount(b);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   877
  int minlen = alen < blen ? alen : blen;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   878
  int result = memcmp(bvBytes(a), bvBytes(b), minlen);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   879
  if (result == 0) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   880
    result = alen - blen;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   881
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   882
  if (result < 0) return mkSmi(-1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   883
  if (result > 0) return mkSmi(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   884
  return mkSmi(0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   885
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   886
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   887
static obj prim_slotAt(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   888
  return slotAt(slotAt(args, 0), unSmi(slotAt(args, 1)) - 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   889
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   890
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   891
static obj prim_extendObj(unsigned primNumber, VM &vm, obj args) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   892
  obj v = slotAt(args, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   893
  obj o = slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   894
  obj r = vm.allocObj(slotCount(o) + 1, vm.objClass(o));
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   895
  copy(slotAddr(o, 0), slotAddr(o, slotCount(o)), slotAddr(r, 0));