experiments/little-smalltalk/run.cc
author Tony Garnock-Jones <tonygarnockjones@gmail.com>
Tue, 07 Aug 2018 17:14:14 +0100
changeset 436 f519b01f759b
parent 435 8cad65af7913
child 437 f3b04d3ef973
permissions -rw-r--r--
Simplest method cache in run.cc
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
436
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   118
  static unsigned const methodCacheCount = 2039;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   119
  static unsigned const methodCacheLimit = 3 * methodCacheCount;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   120
  obj methodCache[methodCacheLimit];
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   121
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   122
  struct timespec mutatorStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   123
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   124
  inline obj objClass(obj o) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   125
    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
   126
  }
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
  string className(obj c) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   129
    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
   130
    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
   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
  string objClassName(obj o) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   134
    return className(objClass(o));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   135
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   136
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   137
  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
   138
    unsigned heapSize = 8 * 1048576;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   139
    heap.resize(heapSize, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   140
    cerr << "Heap bounds: " << &heap[0] << "-" << &heap[heapSize] << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   141
    allocPtr = &heap[0];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   142
    *allocPtr = (obj) freeHeader(heapSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   143
    allocLimit = allocPtr + heapSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   144
    gcEnabled = 0; // during image loading
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   145
    fill(&primitiveTable[0], &primitiveTable[256], unhandledPrimitive);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   146
    rootStack = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   147
    new Root(this, &_nil);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   148
    new Root(this, &_true);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   149
    new Root(this, &_false);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   150
    new Root(this, &_Array);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   151
    new Root(this, &_Block);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   152
    new Root(this, &_Context);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   153
    new Root(this, &_Integer);
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   154
    new Root(this, &_activeCtx);
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   155
    new Root(this, &_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   156
    new Root(this, &_j);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   157
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   158
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   159
  void scheduleMark(deque<obj *> &q, obj *p) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   160
    // cerr << "  scheduling mark of " << p << " (" << *p << ")" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   161
    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
   162
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   163
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   164
  void gc() {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   165
    struct timespec gcStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   166
    clock_gettime(CLOCK_MONOTONIC, &gcStart);
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
    unsigned liveCount = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   169
    unsigned scanCount = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   170
    unsigned byteCount = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   171
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   172
    deque<obj *> q;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   173
    // cerr << "VM this = " << this << "-" << (this + 1) << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   174
    for (Root *r = rootStack; r != 0; r = r->next) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   175
      scheduleMark(q, r->ptr);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   176
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   177
    while (!q.empty()) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   178
      obj *op = q.front();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   179
      q.pop_front();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   180
      scanCount++;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   181
      // cerr << "Scan of " << op;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   182
      obj o = *op;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   183
      // cerr << " (" << o << ")" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   184
      if (isSmi(o)) continue;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   185
      if (isMarked(o)) continue;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   186
      // cerr << "Marking " << o << " which is "; print(cerr, o); cerr << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   187
      mark(o);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   188
      liveCount++;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   189
      scheduleMark(q, classAddr(o));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   190
      if (!isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   191
        for (int i = 0; i < slotCount(o); i++) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   192
          scheduleMark(q, slotAddr(o, i));
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
      } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   195
        byteCount += bytesCount(o);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   196
      }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   197
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   198
    // {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   199
    //   obj *p = &heap[0];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   200
    //   cerr << "-------------- allocBase == " << &heap[0] << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   201
    //   while (p < allocLimit) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   202
    //     obj o = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   203
    //     cerr << o << (isUnused(o) ? " (unused)" :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   204
    //                   isMarked(o) ? " (marked) " :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   205
    //                   " (      ) ");
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   206
    //     if (isUnused(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   207
    //       p++;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   208
    //     } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   209
    //       if (isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   210
    //         cerr << bytesCount(o) << " bytes";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   211
    //       } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   212
    //         cerr << slotCount(o) << " slots";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   213
    //       }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   214
    //       p += objSize(p);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   215
    //       if (!isMarked(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   216
    //         // TODO remove
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   217
    //         uint8_t *stomple = ((uint8_t *) o) + sizeof(obj);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   218
    //         unsigned stompcount = ((uint8_t *) p) - stomple;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   219
    //         cerr << " (stomping on " << stompcount << " bytes)";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   220
    //         memset(stomple, 0x5a, stompcount);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   221
    //       }
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
    //     cerr << endl;
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
    //   cerr << "-------------- end of sweep" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   226
    // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   227
    allocPtr = &heap[0];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   228
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   229
    struct timespec gcEnd;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   230
    clock_gettime(CLOCK_MONOTONIC, &gcEnd);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   231
    long gc_us = gcEnd - gcStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   232
    long mutator_us = gcStart - mutatorStart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   233
    double mutator_percentage = (100.0 * mutator_us) / (mutator_us + gc_us);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   234
    cerr << " complete in " << gc_us << "??s."
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   235
         << " Mutator ran for " << mutator_us << "??s (" << mutator_percentage << "%)."
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   236
         << " " << liveCount << " live objects; "
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   237
         << scanCount << " words scanned, "
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   238
         << byteCount << " bytes skipped."
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   239
         << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   240
    mutatorStart = gcEnd;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   241
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   242
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   243
  unsigned objSize(obj o) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   244
    if (isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   245
      return (roundUpAllocation(bytesCount(o)) / sizeof(obj)) + 2;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   246
    } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   247
      return slotCount(o) + 2;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   248
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   249
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   250
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   251
  unsigned chunkSizeAt(obj *p) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   252
    obj o = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   253
    return
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   254
      isUnused(o) ? 1 :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   255
      isMarked(o) ? 0 :
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   256
      objSize(o);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   257
  }
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
  void findFree(unsigned nObj, obj *&candidate, unsigned &candidateSize) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   260
    candidate = allocPtr;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   261
    // cerr << "Hunting for " << nObj << " words at " << candidate << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   262
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   263
  restart:
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   264
    obj *scan = candidate;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   265
    candidateSize = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   266
    while ((candidateSize < nObj) && (scan < allocLimit)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   267
      unsigned nextChunkSize = chunkSizeAt(scan);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   268
      if (nextChunkSize == 0) { // marked block - not at allocLimit by loop condition
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   269
        unmark((obj) scan);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   270
        candidate = scan + objSize(scan);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   271
        goto restart;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   272
      }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   273
      candidateSize += nextChunkSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   274
      // cerr << "  after nextChunkSize==" << nextChunkSize
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   275
      //      << " at " << scan << "-" << (scan + nextChunkSize)
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   276
      //      << ", candidateSize==" << candidateSize << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   277
      scan += nextChunkSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   278
    }
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
    // cerr << "  Final candidateSize: " << candidateSize << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   281
    if (candidateSize < nObj) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   282
      candidate = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   283
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   284
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   285
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   286
  // void growHeap() {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   287
  //   // BOGUS: resizing likely moves the base pointer, forcing rewrite
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   288
  //   // 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
   289
  //   // 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
   290
  //   // guarantee that only the pointers in the root set are live.
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   291
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   292
  //   unsigned oldSize = heap.size();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   293
  //   unsigned newSize = oldSize * 2;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   294
  //   cerr << "Growing heap from " << oldSize << " words to " << newSize << " words" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   295
  //   heap.resize(newSize, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   296
  //   cerr << "Heap bounds: " << &heap[0] << "-" << &heap[newSize] << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   297
  //   allocPtr = &heap[oldSize];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   298
  //   *allocPtr = (obj) freeHeader(newSize - oldSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   299
  //   allocLimit = allocPtr + newSize;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   300
  // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   301
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   302
  obj *allocBlock(unsigned nObj) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   303
    obj *candidate = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   304
    unsigned candidateSize = 0;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   305
    findFree(nObj, candidate, candidateSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   306
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   307
    if (candidate == 0) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   308
      if (gcEnabled) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   309
        cerr << "gc()...";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   310
        storeRegisters();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   311
        gc();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   312
        findFree(nObj, candidate, candidateSize);
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
      if (candidate == 0) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   315
        cerr << "Out of memory, heap resizing not yet implemented" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   316
        exit(1);
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
      // while (candidate == 0) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   319
      //   growHeap();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   320
      //   findFree(nObj, candidate, candidateSize);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   321
      // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   322
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   323
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   324
    // cerr << "  candidate==" << candidate
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   325
    //      << ", candidateSize==" << candidateSize
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   326
    //      << ", nObj+2==" << (nObj + 2)
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   327
    //      << ", possibleLeftoverInclHeader==" << (candidateSize - nObj)
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   328
    //      << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   329
    assert(candidateSize >= nObj);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   330
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   331
    if (candidateSize > (nObj + 2)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   332
      allocPtr = candidate + nObj;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   333
      *allocPtr = (obj) freeHeader(candidateSize - nObj);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   334
    } else {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   335
      fill(candidate + nObj, candidate + candidateSize, (obj) 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   336
      allocPtr = candidate + candidateSize;
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
    // if (allocPtr == allocLimit) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   340
    //   cerr << "Next allocation will GC!" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   341
    // }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   342
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   343
    return candidate;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   344
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   345
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   346
  obj allocObj(unsigned nSlots, obj klass) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   347
    obj *p = allocBlock(nSlots + 2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   348
    obj result = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   349
    *p++ = (obj) objHeader(nSlots, 0);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   350
    *p++ = klass;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   351
    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
   352
    return result;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   353
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   354
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   355
  obj allocBytes(unsigned nBytes, obj klass) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   356
    obj *p = allocBlock((roundUpAllocation(nBytes) / sizeof(obj)) + 2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   357
    obj result = (obj) p;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   358
    *p++ = (obj) objHeader(nBytes, 1);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   359
    *p++ = klass;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   360
    return result;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   361
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   362
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   363
  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
   364
    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
   365
    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
   366
    return o;
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 allocRawArray(unsigned n) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   370
    return allocObj(n, _Array);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   371
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   372
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   373
  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
   374
    obj o = allocRawArray(n);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   375
    _fillWith(o, n, v);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   376
    return o;
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
  obj allocArray(unsigned n) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   380
    return allocArray(n, _nil);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   381
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   382
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   383
  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
   384
    if (isSmi(o)) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   385
      f << unSmi(o);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   386
      return;
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
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   389
    string className = objClassName(o);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   390
    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
   391
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   392
    if (!isString) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   393
      f << className;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   394
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   395
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   396
    if (isBytes(o)) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   397
      f << (isString ? '\"' : '{');
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   398
      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
   399
      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
   400
      f << hex;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   401
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   402
      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
   403
        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
   404
        if (isString) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   405
          switch (c) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   406
            case '\"': f << "\\\""; break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   407
            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
   408
            default: f << c; break;
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
        } else {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   411
          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
   412
        }
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
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   415
      f.flags(saved);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   416
      f.fill(fill);
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
      f << (isString ? '\"' : '}');
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   419
    } else {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   420
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   421
  }
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
  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
   424
    ifstream f(filename);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   425
    vector<obj> table;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   426
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   427
    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
   428
    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
   429
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   430
    while (true) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   431
      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
   432
      if (!f) break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   433
      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
   434
      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
   435
      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
   436
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   437
      switch (code) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   438
        case 0:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   439
          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
   440
          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
   441
          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
   442
          break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   443
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   444
        case 1: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   445
          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
   446
          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
   447
          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
   448
          table.push_back(bv);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   449
          break;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   450
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   451
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   452
        case 2: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   453
          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
   454
          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
   455
            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
   456
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   457
          table.push_back(o);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   458
          break;
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
        default:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   462
          return 0; // unhandled code
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   463
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   464
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   465
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   466
    cerr << "Loading: starting fixup" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   467
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   468
    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
   469
      obj o = *it;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   470
      if (!isSmi(o)) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   471
        *classAddr(o) = table[unSmi(*classAddr(o))];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   472
        if (!isBytes(o)) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   473
          for (unsigned i = 0; i < slotCount(o); i++) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   474
            *slotAddr(o, i) = table[unSmi(*slotAddr(o, i))];
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   475
          }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   476
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   477
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   478
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   479
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   480
    cerr << "Loading: fixup complete" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   481
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   482
    _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
   483
    _true = table[1];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   484
    _false = table[2];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   485
    _Array = table[3];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   486
    _Block = table[4];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   487
    _Context = table[5];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   488
    _Integer = table[6];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   489
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   490
    return 1;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   491
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   492
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   493
  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
   494
    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
   495
    unsigned selectorLen = bytesCount(selector);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   496
    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
   497
    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
   498
      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
   499
      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
   500
      // 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
   501
      if ((bytesCount(mname) == selectorLen) &&
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   502
          (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
   503
        return m;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   504
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   505
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   506
    return 0;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   507
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   508
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   509
  void callMethod_i_j() {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   510
    unsigned tempCount = (unsigned) unSmi(slotAt(_j, 4));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   511
    unsigned maxStack = (unsigned) unSmi(slotAt(_j, 3));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   512
    {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   513
      obj ctx = allocObj(7, _Context);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   514
      slotAtPut(ctx, 0, _j); // method
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   515
      slotAtPut(ctx, 1, _i); // args
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   516
      _i = ctx;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   517
    }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   518
    slotAtPut(_i, 2, allocArray(tempCount));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   519
    slotAtPut(_i, 3, allocArray(maxStack));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   520
    slotAtPut(_i, 4, mkSmi(0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   521
    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
   522
    slotAtPut(_i, 6, _activeCtx);
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   523
    loadContext(_i);
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   524
    _i = _j = _nil;
431
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
  void push(obj v) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   528
    slotAtPut(__stack, __stackTop++, v);
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 pop() {
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);
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
  obj peek() {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   536
    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
   537
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   538
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   539
  uint8_t nextByte() {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   540
    return __bytecode[__ip++];
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   541
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   542
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   543
  void popArray_i(uint8_t count) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   544
    _i = allocRawArray(count);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   545
    __stackTop -= count;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   546
    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
   547
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   548
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   549
  void loadContext(obj ctx);
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
  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
   552
    loadContext(ctx);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   553
    push(v);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   554
  }
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
  void storeRegisters() {
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   557
    slotAtPut(_activeCtx, 4, mkSmi(__ip));
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   558
    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
   559
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   560
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   561
  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
   562
    while (c != _nil) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   563
      // 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
   564
      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
   565
      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
   566
      c = slotAt(c, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   567
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   568
    return 0;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   569
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   570
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   571
  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
   572
    storeRegisters();
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   573
    // cerr << "Sending " << bvString(_j) << " via " << className(c) << " to ";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   574
    // 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
   575
    // cerr << endl;
436
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   576
    unsigned probe = ((((intptr_t) c) * 5 + ((intptr_t) _j)) % methodCacheCount) * 3;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   577
    obj method;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   578
    if ((methodCache[probe] == c) && (methodCache[probe + 1] == _j)) {
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   579
      method = methodCache[probe + 2];
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   580
    } else {
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   581
      method = lookupMethod(c, _j);
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   582
      methodCache[probe] = c;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   583
      methodCache[probe + 1] = _j;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   584
      methodCache[probe + 2] = method;
f519b01f759b Simplest method cache in run.cc
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 435
diff changeset
   585
    }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   586
    if (method == 0) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   587
      cerr << "DNU ";
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   588
      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
   589
      cerr << ' ';
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   590
      print(cerr, _j);
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   591
      cerr << endl;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   592
      exit(2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   593
    }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   594
    _j = method;
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   595
    callMethod_i_j();
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   596
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   597
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   598
  void interpret() {
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   599
    while (_activeCtx != _nil) {
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   600
      uint8_t opcode, arg;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   601
      opcode = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   602
      arg = opcode & 0xf;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   603
      opcode = opcode >> 4;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   604
      if (opcode == 0) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   605
        opcode = arg;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   606
        arg = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   607
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   608
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   609
      // 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
   610
      // for (int i = 0; i < __stackTop; i++) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   611
      //   cerr << ' ';
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   612
      //   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
   613
      // }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   614
      // cerr << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   615
      // cerr << flush;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   616
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   617
      switch (opcode) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   618
        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
   619
        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
   620
        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
   621
        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
   622
        case 5:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   623
          if (arg < 10) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   624
            push(mkSmi(arg));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   625
          } else {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   626
            switch (arg) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   627
              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
   628
              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
   629
              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
   630
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   631
          }
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
        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
   634
        case 7: slotAtPut(__temps, arg, peek()); continue;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   635
        case 8: {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   636
          popArray_i(arg);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   637
          push(_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   638
          _i = _nil;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   639
          continue;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   640
        }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   641
        case 9: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   642
          _i = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   643
          _j = slotAt(__literals, arg);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   644
          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
   645
          continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   646
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   647
        case 10:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   648
          switch (arg) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   649
            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
   650
            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
   651
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   652
        case 11: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   653
          _j = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   654
          _i = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   655
          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
   656
            switch (arg) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   657
              case 0: push((unSmi(_i) < unSmi(_j)) ? _true : _false); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   658
              case 1: push((unSmi(_i) <= unSmi(_j)) ? _true : _false); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   659
              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
   660
            }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   661
            _i = _j = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   662
          } else {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   663
            {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   664
              obj newArgs = allocRawArray(2);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   665
              slotAtPut(newArgs, 0, _i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   666
              slotAtPut(newArgs, 1, _j);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   667
              _i = newArgs;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   668
            }
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   669
            switch (arg) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   670
              case 0: _j = allocBytes("<", _nil); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   671
              case 1: _j = allocBytes("<=", _nil); break;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   672
              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
   673
            }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   674
            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
   675
          }
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   676
          continue;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   677
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   678
        case 12: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   679
          uint8_t target = nextByte();
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   680
          _i = allocObj(10, _Block);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   681
          slotAtPut(_i, 0, __method);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   682
          slotAtPut(_i, 1, __args);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   683
          slotAtPut(_i, 2, __temps);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   684
          slotAtPut(_i, 3, __stack);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   685
          slotAtPut(_i, 4, mkSmi(__ip));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   686
          slotAtPut(_i, 5, mkSmi(0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   687
          slotAtPut(_i, 6, __prevCtx);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   688
          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
   689
          slotAtPut(_i, 8, _activeCtx);
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   690
          slotAtPut(_i, 9, mkSmi(__ip));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   691
          push(_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   692
          _i = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   693
          __ip = target;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   694
          continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   695
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   696
        case 13: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   697
          uint8_t primNumber = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   698
          // 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
   699
          switch (primNumber) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   700
            case 6: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   701
              loadContext(pop());
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   702
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   703
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   704
            case 8: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   705
              _j = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   706
              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
   707
              unsigned argcount = arg - 1;
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   708
              copy(slotAddr(__stack, __stackTop - argcount),
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   709
                   slotAddr(__stack, __stackTop),
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   710
                   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
   711
              __stackTop = __stackTop - argcount;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   712
              storeRegisters();
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   713
              _i = allocObj(10, _Block);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   714
              slotAtPut(_i, 0, slotAt(_j, 0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   715
              slotAtPut(_i, 1, slotAt(_j, 1));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   716
              slotAtPut(_i, 2, slotAt(_j, 2));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   717
              slotAtPut(_i, 3, allocArray(slotCount(slotAt(_j, 3))));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   718
              slotAtPut(_i, 4, slotAt(_j, 9));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   719
              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
   720
              slotAtPut(_i, 6, slotAt(_activeCtx, 6));
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   721
              slotAtPut(_i, 7, slotAt(_j, 7));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   722
              slotAtPut(_i, 8, slotAt(_j, 8));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   723
              slotAtPut(_i, 9, slotAt(_j, 9));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   724
              loadContext(_i);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   725
              _i = _j = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   726
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   727
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   728
            case 34: return;
434
5c04878ec48e Minor refactoring, eliding buildContext as a separate entity
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 433
diff changeset
   729
            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
   730
            default:
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   731
              popArray_i(arg);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   732
              push(primitiveTable[primNumber](primNumber, *this, _i));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   733
              _i = _nil;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   734
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   735
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   736
        }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   737
        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
   738
        case 15:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   739
          switch (arg) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   740
            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
   741
            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
   742
            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
   743
            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
   744
            case 5: pop(); continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   745
            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
   746
            case 7: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   747
              unsigned target = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   748
              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
   749
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   750
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   751
            case 8: {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   752
              unsigned target = nextByte();
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   753
              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
   754
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   755
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   756
            case 11: {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   757
              _i = pop();
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   758
              _j = slotAt(__literals, nextByte());
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   759
              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
   760
              continue;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   761
            }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   762
            default:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   763
              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
   764
              exit(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   765
          }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   766
        default:
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   767
          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
   768
          exit(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   769
      }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   770
    }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   771
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   772
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   773
  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
   774
    primitiveTable[primNumber] = handler;
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
};
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
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
   779
  _activeCtx = ctx;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   780
  if (ctx != _nil) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   781
    __method = slotAt(ctx, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   782
    __args = slotAt(ctx, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   783
    __temps = slotAt(ctx, 2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   784
    __stack = slotAt(ctx, 3);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   785
    __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
   786
    __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
   787
    __prevCtx = slotAt(ctx, 6);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   788
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   789
    __receiver = slotAt(__args, 0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   790
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   791
    __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
   792
    __literals = slotAt(__method, 2);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   793
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   794
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   795
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   796
Root::Root(VM *vm, obj *ptr) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   797
  this->vm = vm;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   798
  this->ptr = ptr;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   799
  this->next = vm->rootStack;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   800
  vm->rootStack = this;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   801
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   802
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   803
Root::~Root() {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   804
  if (vm->rootStack != this) {
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   805
    cerr << "Root stack corruption" << endl;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   806
    exit(1);
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   807
  }
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   808
  vm->rootStack = next;
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   809
}
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   810
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   811
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
   812
  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
   813
  exit(1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   814
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   815
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   816
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
   817
  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
   818
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   819
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   820
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
   821
  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
   822
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   823
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   824
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
   825
  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
   826
  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
   827
  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
   828
  return mkSmi(slotCount(o));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   829
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   830
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   831
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
   832
  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
   833
  return slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   834
}
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
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
   837
  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
   838
  _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
   839
  return r;
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
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   842
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
   843
  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
   844
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   845
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   846
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
   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_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
   851
  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
   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_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
   855
  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
   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_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
   859
  // TODO overflow checks
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   860
  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
   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_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
   864
  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
   865
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   866
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   867
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
   868
  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
   869
}
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
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
   872
  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
   873
  return slotAt(args, 1);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   874
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   875
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   876
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
   877
  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
   878
  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
   879
  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
   880
  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
   881
  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
   882
  return r;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   883
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   884
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   885
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
   886
  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
   887
  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
   888
  int alen = bytesCount(a);
432
527bdc1042a9 Typo fix
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 431
diff changeset
   889
  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
   890
  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
   891
  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
   892
  if (result == 0) {
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   893
    result = alen - blen;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   894
  }
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   895
  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
   896
  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
   897
  return mkSmi(0);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   898
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   899
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   900
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
   901
  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
   902
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   903
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   904
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
   905
  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
   906
  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
   907
  obj r = vm.allocObj(slotCount(o) + 1, vm.objClass(o));
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   908
  copy(slotAddr(o, 0), slotAddr(o, slotCount(o)), slotAddr(r, 0));
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   909
  slotAtPut(r, slotCount(o), v);
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   910
  return r;
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   911
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   912
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   913
static obj prim_createWindow(unsigned primNumber, VM &vm, obj args) {
433
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   914
  cout << "Creating window ";
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   915
  vm.print(cout, slotAt(args, 0));
73fb551bd557 Garbage collector.
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents: 432
diff changeset
   916
  cout << endl;
431
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   917
  return vm.allocObj(0, slotAt(args, 0));
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   918
}
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <tonygarnockjones@gmail.com>
parents:
diff changeset
   919
97c12bf829d8 WIP C++ simple interpreter, product of yesterday evening's work
Tony Garnock-Jones <