示例#1
0
// Create either a static or an uncounted string.
// Diffrence between static and uncounted is in the lifetime
// of the string. Static are alive for the lifetime of the process.
// Uncounted are not ref counted but will be deleted at some point.
ALWAYS_INLINE
StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) {
  if (UNLIKELY(sl.len > StringData::MaxSize)) {
    throw_string_too_large(sl.len);
  }

  auto const cc = CapCode::ceil(sl.len);
  auto const need = cc.decode() + kCapOverhead;
  auto const sd = static_cast<StringData*>(
    trueStatic ? low_malloc(need) : malloc(need)
  );
  auto const data = reinterpret_cast<char*>(sd + 1);

  sd->m_data = data;
  auto const count = trueStatic ? StaticValue : UncountedValue;
  sd->m_hdr.init(cc, HeaderKind::String, count);
  sd->m_len = sl.len; // m_hash is computed soon.

  data[sl.len] = 0;
  auto const mcret = memcpy(data, sl.ptr, sl.len);
  auto const ret = reinterpret_cast<StringData*>(mcret) - 1;
  // Recalculating ret from mcret avoids a spill.
  ret->preCompute();                    // get m_hash right

  assert(ret == sd);
  assert(ret->isFlat());
  assert(trueStatic ? ret->isStatic() : ret->isUncounted());
  assert(ret->checkSane());
  return ret;
}
示例#2
0
文件: parser.c 项目: doly/femtoutil
// add last
cons_t *add_list(cons_t *l, int type, consvalue_t v){
	cons_t *top;
	if(l == NULL){
		l = (cons_t *)low_malloc(sizeof(cons_t));
		top = l;
	}else{
		top = l;
		while(l->cdr != NULL) l = l->cdr;
		l->cdr = (cons_t *)low_malloc(sizeof(cons_t));
		l = l->cdr;
	}
	l->type = type;
	l->v = v;
	l->cdr = NULL;
	return top;
}
示例#3
0
文件: parser.c 项目: doly/femtoutil
cons_t *create_list(Token *token)
{
	cons_t *list = NULL;
	consvalue_t value;
	value.i = 0;

	while(next_token(token)){
		switch(token->type){
		case TOKEN_BRACE_OPEN:
			value.car = create_list(token);
			list = add_list(list, TYPE_CAR, value);
			break;

		case TOKEN_INT:
			value.i = token->num;
			list = add_list(list, TYPE_INT, value);
			break;

		case TOKEN_STR:
			if(strcmp(token->str, "if") == 0){
				list = add_list(list, TYPE_IF, value);
			}else if(strcmp(token->str, "t") == 0){
				list = add_list(list, TYPE_T, value);
			}else if(strcmp(token->str, "nil") == 0){
				list = add_list(list, TYPE_NIL, value);
			}else if(strcmp(token->str, "setq") == 0){
				list = add_list(list, TYPE_SETQ, value);
			}else if(strcmp(token->str, "defun") == 0){
				list = add_list(list, TYPE_DEFUN, value);
			}else{
				// variable or function ?
				int length = strlen(token->str);
				value.str = (char *)low_malloc(length+1);
				strcpy(value.str, token->str);
				list = add_list(list, TYPE_STR, value);
			}
			break;

		case TOKEN_OPERATE:
			list = add_list(list, token->num, value);
			break;

		case TOKEN_BRACE_CLOSE:
			goto end;

		default:
			printf("PARSER ERROR!!\n");
			goto end;
		}
	}
end:
	return list;
}
示例#4
0
文件: func.c 项目: doly/femtoutil
Func *add_function(char *name, cons_t *arg, Code *code, int code_index)
{
	Func *f = (Func *)low_malloc(sizeof(Func));
	f->name = name;
	f->arg = arg;
	f->code = code;
	f->code_index = code_index;
	// count
	f->arg_count = 0;
	while(arg != NULL){
		f->arg_count++;
		arg = arg->cdr;
	}
	f->next = funclist;
	funclist = f;
	return f;
}
示例#5
0
// create either a static or an uncounted string.
// Diffrence between static and uncounted is in the lifetime
// of the string. Static are alive for the lifetime of the process.
// Uncounted are not ref counted but will be deleted at some point.
ALWAYS_INLINE
StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) {
  if (UNLIKELY(sl.len > StringData::MaxSize)) {
    throw_string_too_large(sl.len);
  }

  auto const cc = CapCode::ceil(sl.len);
  auto const need = cc.decode() + kCapOverhead;
  auto const sd = static_cast<StringData*>(
    trueStatic ? low_malloc(need) : malloc(need)
  );
  auto const data = reinterpret_cast<char*>(sd + 1);

  sd->m_data        = data;
  sd->m_hdr.init(cc, HeaderKind::String, 0);
  sd->m_lenAndHash  = sl.len; // hash=0

  data[sl.len] = 0;
  auto const mcret = memcpy(data, sl.ptr, sl.len);
  auto const ret   = reinterpret_cast<StringData*>(mcret) - 1;
  // Recalculating ret from mcret avoids a spill.

  assert(ret->m_hash == 0);
  assert(ret->getCount() == 0);
  if (trueStatic) {
    ret->setStatic();
  } else {
    ret->setUncounted();
  }

  assert(ret == sd);
  assert(ret->isFlat());
  assert(trueStatic ? ret->isStatic() : ret->isUncounted());
  assert(ret->checkSane());
  return ret;
}
示例#6
0
// create either a static or an uncounted string.
// Diffrence between static and uncounted is in the lifetime
// of the string. Static are alive for the lifetime of the process.
// Uncounted are not ref counted but will be deleted at some point.
StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) {
  if (UNLIKELY(sl.len > StringData::MaxSize)) {
    throw_string_too_large(sl.len);
  }

  auto const encodable = roundUpPackedCap(sl.len);
  auto const need = encodable + kCapOverhead;
  auto const sd = static_cast<StringData*>(
    trueStatic ? low_malloc(need) : malloc(need)
  );
  auto const data = reinterpret_cast<char*>(sd + 1);
  auto const capCode = packedCapToCode(encodable);

  sd->m_data        = data;
  sd->m_capAndCount = HeaderKind::String << 24 | capCode; // count=0
  sd->m_lenAndHash  = sl.len; // hash=0

  data[sl.len] = 0;
  auto const mcret = memcpy(data, sl.ptr, sl.len);
  auto const ret   = reinterpret_cast<StringData*>(mcret) - 1;
  // Recalculating ret from mcret avoids a spill.

  assert(ret->m_hash == 0);
  assert(ret->m_count == 0);
  if (trueStatic) {
    ret->setStatic();
  } else {
    ret->setUncounted();
  }

  assert(ret == sd);
  assert(ret->isFlat());
  assert(trueStatic ? ret->isStatic() : ret->isUncounted());
  assert(ret->checkSane());
  return ret;
}