Beispiel #1
0
Closure *
loadClosure(const char *filename,
            FILE *f, const StringTabEntry *strings,
            HashTable *itbls, HashTable *closures)
{
  u4 i;
  u4 magic = fget_u4(f);
  assert(magic == CLOSURE_MAGIC);
  char *clos_name = loadId(f, strings, ".");
  u4 payloadsize = fget_varuint(f);
  char *itbl_name = loadId(f, strings, ".");

  Closure *cl = allocStaticClosure(wordsof(ClosureHeader) + payloadsize);
  Closure *fwd_ref;
  InfoTable* info = HashTable_lookup(itbls, itbl_name);
  LC_ASSERT(info != NULL && info->type != INVALID_OBJECT);

  // Fill in closure payload.  May create forward references to
  // the current closure.
  setInfo(cl, info);
  xfree(itbl_name);
  for (i = 0; i < payloadsize; i++) {
    LD_DBG_PR(1, "Loading payload for: %s [%d]\n", clos_name, i);
    u1 dummy;
    loadLiteral(filename, f, &dummy, &cl->payload[i], strings, itbls, closures);
  }

  fwd_ref = HashTable_lookup(closures, clos_name);
  if (fwd_ref != NULL) {
    LD_DBG_PR(2, "Fixing closure forward ref: %s, %p -> %p\n", clos_name, fwd_ref, cl);
    // fixup forward refs
    void **p, *next;
    for (p = (void**)fwd_ref->payload[0]; p != NULL; p = next) {
      next = *p;
      *p = (void*)cl;
    }

    xfree(fwd_ref);
    HashTable_update(closures, clos_name, cl);
    // The key has been allocated by whoever installed the first
    // forward reference.
    xfree(clos_name);

  } else {

    HashTable_insert(closures, clos_name, cl);

  }
  return cl;
}
Beispiel #2
0
int
isModuleLoaded(const char *moduleName)
{
  Module *mdl;
  mdl = HashTable_lookup(G_loader->loadedModules, moduleName);

  // If the module is currently being loaded, then its string table
  // will be non-empty.

  return (mdl != NULL) && (mdl->strings == NULL);
}
Beispiel #3
0
// Postorder traversal
void
loadModule_aux(const char *moduleName, u4 level)
{
  char     *filename;
  Module   *mdl;
  FILE     *f;
  int       i;

  mdl = (Module*)HashTable_lookup(G_loader->loadedModules, moduleName);

  if (mdl != NULL) {
    // Module is either already loaded, or currently in process of
    // being loaded.
      return;
  }

  filename = findModule(moduleName);

  for (i = 0; i < level; i++) fputc(' ', stderr);
  fprintf(stderr, "> Loading %s ...(%s)\n", moduleName, filename);

  f = fopen(filename, "rb");
  if (f == NULL) {
    fprintf(stderr, "ERROR: Could not open file: %s\n",
            filename);
    exit(14);
  }

  mdl = loadModuleHeader(f, filename);

  HashTable_insert(G_loader->loadedModules, moduleName, mdl);

  // Load dependencies first.  This avoids creating many forward
  // references.  The downside is that we keep more file descriptors
  // open.
  for (i = 0; i < mdl->numImports; i++)
    loadModule_aux(mdl->imports[i], level + 1);

  loadModuleBody(filename, f, mdl);

  fclose(f);

  // We now don't need the string table anymore.
  xfree(mdl->strings);
  mdl->strings = NULL;

  for (i = 0; i < level; i++) fputc(' ', stderr);
  fprintf(stderr, "< DONE   (%s)\n", moduleName);
}
Beispiel #4
0
void LexParser_syncLastVar(LexParser * self) {
	HashTableItem * i;
	iVar * v;
	switch (self->idMode) {
	case lp_insertOnly:
		if (HashTable_insertNew(self->symbolTable, self->str.buff,
				&(self->lastSymbol)) != ht_inserted) {
			Definition_err_throw(self); // redefinition
		}
		break;
	case lp_parseParams:
		v = iVar__init__();
		self->lastSymbol = v;
		iFunction_addParam(self->lastFunction, self->lastSymbol,
				strdup(self->str.buff));
		break;
	case lp_fnSearch:
		i = HashTable_lookup(self->symbolTable, self->str.buff);
		if (!i) {
			if (HashTable_insertNew(self->symbolTable, self->str.buff,
					&(self->lastSymbol)) != ht_inserted) {
				Definition_err_throw(self);  // redefinition
			}
			self->lastSymbol->type = iFn;
			self->lastSymbol->val.fn = iFunction__init__();
			self->lastSymbol->val.fn->name = strdup(self->str.buff);
		} else {
			if (i->var->type != iFn || i->var->val.fn->bodyFound)
				Definition_err_throw(self);
			self->lastSymbol = i->var;
		}
		self->lastFunction = self->lastSymbol->val.fn;
		break;
	case lp_searchOnly:
		i = HashTable_lookupEverywhere(self->symbolTable, self->str.buff);
		if (!i) {
			Definition_err_throw(self);
		}
		self->lastSymbol = i->var;
		break;
	case lp_ignore:
		break;
	default:
		Lex_throwError(self,
				"LexParser doesn't know whether to search or insert new id\n");
	}
}
Beispiel #5
0
void
loadLiteral(const char *filename,
            FILE *f, u1 *littype /*out*/, Word *literal /*out*/,
            const StringTabEntry *strings, HashTable *itbls,
            HashTable *closures)
{
  u4 i;
  *littype = fget_u1(f);
  switch (*littype) {
  case LIT_INT:
    *literal = (Word)fget_varsint(f);
    break;
  case LIT_CHAR:
    *literal = (Word)fget_varuint(f);
    break;
  case LIT_WORD:
    *literal = (Word)fget_varuint(f);
    break;
  case LIT_FLOAT:
    *literal = (Word)fget_u4(f);
    break;
  case LIT_STRING:
    i = fget_varuint(f);
    *literal = (Word)strings[i].str;
    break;
  case LIT_CLOSURE:
    { char *clname = loadId(f, strings, ".");
      Closure *cl = HashTable_lookup(closures, clname);
      if (cl == NULL) {
        // 1st forward ref, create the link
        cl = xmalloc(sizeof(ClosureHeader) + sizeof(Word));
        setInfo(cl, NULL);
        cl->payload[0] = (Word)literal;
        *literal = (Word)NULL;
        LD_DBG_PR(2, "Creating forward reference %p for `%s', %p\n",
                  cl, clname, literal);
        HashTable_insert(closures, clname, cl);
      } else if (getInfo(cl) == NULL) {
        // forward ref (not the first), insert into linked list
        LD_DBG_PR(2, "Linking forward reference %p (%s, target: %p)\n",
                  cl, clname, literal);
        *literal = (Word)cl->payload[0];
        cl->payload[0] = (Word)literal;
        xfree(clname);
      } else {
        *literal = (Word)cl;
        xfree(clname);
      }
    }
    break;
  case LIT_INFO:
    { char *infoname = loadId(f, strings, ".");
      InfoTable *info = HashTable_lookup(itbls, infoname);
      FwdRefInfoTable *info2;
      if (info == NULL) {
	// 1st forward ref
	info2 = xmalloc(sizeof(FwdRefInfoTable));
	info2->i.type = INVALID_OBJECT;
	info2->next = (void**)literal;
	*literal = (Word)NULL;
	HashTable_insert(itbls, infoname, info2);
      } else if (info->type == INVALID_OBJECT) {
	// subsequent forward ref
	info2 = (FwdRefInfoTable*)info;
	*literal = (Word)info2->next;
	info2->next = (void**)literal;
	xfree(infoname);
      } else {
	*literal = (Word)info;
	xfree(infoname);
      }
    }
    break;
  default:
    fprintf(stderr, "ERROR: Unknown literal type (%d) "
            "when loading file: %s\n",
            *littype, filename);
    exit(1);
  }
}
Beispiel #6
0
InfoTable *
loadInfoTable(const char *filename,
              FILE *f, const StringTabEntry *strings,
              HashTable *itbls, HashTable *closures)
{
  u4 magic = fget_u4(f);
  assert(magic == INFO_MAGIC);

  char *itbl_name = loadId(f, strings, ".");
  u2 cl_type = fget_varuint(f);
  InfoTable *new_itbl = NULL;
  FwdRefInfoTable *old_itbl = HashTable_lookup(itbls, itbl_name);

  if (old_itbl && old_itbl->i.type != INVALID_OBJECT) {
    fprintf(stderr, "ERROR: Duplicate info table: %s\n",
            itbl_name);
    exit(1);
  }

  switch (cl_type) {
  case CONSTR:
    // A statically allocated constructor
    {
      ConInfoTable *info = allocInfoTable(wordsof(ConInfoTable));
      info->i.type = cl_type;
      info->i.tagOrBitmap = fget_varuint(f);  // tag
      Word sz = fget_varuint(f);
      assert(sz <= 32);
      info->i.size = sz;
      info->i.layout.bitmap = sz > 0 ? fget_u4(f) : 0;
      // info->i.layout.payload.ptrs = fget_varuint(f);
      // info->i.layout.payload.nptrs = fget_varuint(f);
      info->name = loadId(f, strings, ".");
      new_itbl = (InfoTable*)info;
    }
    break;
  case FUN:
    {
      FuncInfoTable *info = allocInfoTable(wordsof(FuncInfoTable));
      info->i.type = cl_type;
      info->i.tagOrBitmap = 0; // TODO: anything useful to put in here?
      Word sz = fget_varuint(f);
      assert(sz <= 32);
      info->i.size = sz;
      info->i.layout.bitmap = sz > 0 ? fget_u4(f) : 0;
      info->name = loadId(f, strings, ".");
      loadCode(filename, f, &info->code, strings, itbls, closures);
      new_itbl = (InfoTable*)info;
    }
    break;
  case CAF:
  case THUNK:
    {
      ThunkInfoTable *info = allocInfoTable(wordsof(ThunkInfoTable));
      info->i.type = cl_type;
      info->i.tagOrBitmap = 0; // TODO: anything useful to put in here?
      Word sz = fget_varuint(f);
      assert(sz <= 32);
      info->i.size = sz;
      info->i.layout.bitmap = sz > 0 ? fget_u4(f) : 0;
      info->name = loadId(f, strings, ".");
      loadCode(filename, f, &info->code, strings, itbls, closures);
      new_itbl = (InfoTable*)info;
    }
    break;
  default:
    fprintf(stderr, "ERROR: Unknown info table type (%d)", cl_type);
    exit(1);
  }
  // new_itbl is the new info table.  There may have been forward
  // references (even during loading the code for this info table).
  if (old_itbl != NULL) {
    LD_DBG_PR(1, "Fixing itable forward reference for: %s, %p\n", itbl_name, new_itbl);
    void **p, *next;
    LC_ASSERT(old_itbl->i.type == INVALID_OBJECT);

    for (p = old_itbl->next; p != NULL; p = next) {
      next = *p;
      *p = (void*)new_itbl;
    }

    // TODO: fixup forward refs
    xfree(old_itbl);
    HashTable_update(itbls, itbl_name, new_itbl);
    xfree(itbl_name);
  } else {
    HashTable_insert(itbls, itbl_name, new_itbl);
  }

  return new_itbl;
}
Beispiel #7
0
Closure *
lookupClosure(const char *name)
{
  return HashTable_lookup(G_loader->closures, name);
}