Пример #1
0
static void buffer_close(su_state *s, reader_buffer_t *buffer) {
	if (buffer->reader) {
		buffer->reader(NULL, buffer->data);
		su_allocate(s, buffer->buffer, 0);
	}
	su_allocate(s, buffer, 0);
}
Пример #2
0
void lambda(su_state *s, prototype_t *prot, int narg) {
	unsigned i, tmp;
	value_t v;
	function_t *func = su_allocate(s, NULL, sizeof(function_t));

	func->narg = narg;
	func->prot = prot;
	func->num_const = prot->num_const;
	func->num_ups = prot->num_ups;
	func->constants = su_allocate(s, NULL, sizeof(value_t) * prot->num_const);
	func->upvalues = su_allocate(s, NULL, sizeof(value_t) * prot->num_ups);

	for (i = 0; i < func->num_const; i++)
		func->constants[i] = create_value(s, &prot->constants[i]);

	for (i = 0; i < func->num_ups; i++) {
		tmp = s->frame_top - prot->upvalues[i].lv;
		tmp = s->frames[tmp].stack_top + prot->upvalues[i].idx + 1;
		func->upvalues[i] = s->stack[tmp];
	}

	gc_insert_object(s, (gc_t*)func, SU_FUNCTION);
	v.type = SU_FUNCTION;
	v.obj.func = func;
	push_value(s, &v);
}
Пример #3
0
static void free_object(su_state *s, gc_t *obj) {
	function_t *func;
	if (obj->type == SU_FUNCTION) {
		func = (function_t*)obj;
		su_allocate(s, func->constants, 0);
		su_allocate(s, func->upvalues, 0);
	} else if (obj->type == PROTOTYPE) {
		free_prot(s, (prototype_t*)obj);
	} else if (obj->type == SU_LOCAL) {
		/* Remove from the local registry. */
	}
	su_allocate(s, obj, 0);
}
Пример #4
0
gc_t *string_from_cache(su_state *s, const char *str, unsigned size) {
	value_t v;
	string_cache_t entry;
	string_cache_t *entries;
	unsigned hash = murmur(str, size, 0);
	unsigned index = (unsigned)bit_count((int)hash) - 8;
	int i;
	
	if (index < 16) {
		entries = s->string_cache[index];
		for (i = 0; i < STRING_CACHE_SIZE; i++) {
			if (entries[i].hash == hash && !memcmp(entries[i].str->str, str, size))
				return &entries[i].str->gc;
		}
	}
	
	v.type = SU_STRING;
	v.obj.ptr = su_allocate(s, NULL, sizeof(string_t) + size);
	v.obj.str->size = size;
	memcpy(v.obj.str->str, str, size);
	v.obj.str->str[size] = '\0';
	v.obj.str->hash = hash;
	
	if (index < 16) {
		entry.hash = hash;
		entry.str = v.obj.str;
		entries[s->string_cache_head[index]] = entry;
		s->string_cache_head[index] = (s->string_cache_head[index] + 1) % STRING_CACHE_SIZE;
	}
	
	gc_insert_object(s, v.obj.gc_object, SU_STRING);
	return v.obj.gc_object;
}
Пример #5
0
static int buffer_read(su_state *s, reader_buffer_t *buffer, void *dest, size_t num_bytes) {
	unsigned dest_offset = 0;
	do {
		const void *res;
		size_t size = buffer->reader ? (buffer->len - buffer->offset) : num_bytes;
		size_t num = num_bytes < size ? num_bytes : size;
		memcpy(((char*)dest) + dest_offset, &buffer->buffer[buffer->offset], num);

		buffer->offset += num;
		dest_offset += num;
		num_bytes -= num;

		if (!buffer->reader)
			break;

		if (num_bytes == 0) return 0;
		res = buffer->reader(&size, buffer->data);
		if (!res || size == 0) return -1;

		while (buffer->size < size) {
			buffer->size = buffer->size * 2 + 1;
			buffer->buffer = su_allocate(s, buffer->buffer, buffer->size);
		}

		buffer->offset = 0;
		buffer->len = size;
		memcpy(buffer->buffer, res, size);
	} while (num_bytes);
	return 0;
}
Пример #6
0
void su_string_begin(su_state *s, const char *str) {
	size_t len = str ? strlen(str) : 0;
	s->string_builder = (string_t*)su_allocate(s, s->string_builder, sizeof(string_t) + len);
	s->string_builder->size = (unsigned)len;
	s->string_builder->hash = 0;
	if (str)
		memcpy(s->string_builder->str, str, len);
}
Пример #7
0
char *su_string_mem(su_state *s, unsigned size) {
	unsigned offset;
	assert(s->string_builder);
	offset = s->string_builder->size;
	s->string_builder->size += size;
	s->string_builder = (string_t*)su_allocate(s, (void*)s->string_builder, sizeof(string_t) + s->string_builder->size);
	return s->string_builder->str + offset;
}
Пример #8
0
void *su_newdata(su_state *s, unsigned size, const su_data_class_t *vt) {
	value_t v;
	v.type = SU_NATIVEDATA;
	v.obj.data = (native_data_t*)su_allocate(s, NULL, sizeof(native_data_t) + size - 1);
	v.obj.data->vt = (su_data_class_t*)vt;
	gc_insert_object(s, v.obj.gc_object, SU_NATIVEDATA);
	push_value(s, &v);
	return (void*)v.obj.data->data;
}
Пример #9
0
static reader_buffer_t *buffer_open(su_state *s, su_reader reader, void *data) {
	reader_buffer_t *buffer = (reader_buffer_t*)su_allocate(s, NULL, sizeof(reader_buffer_t));
	buffer->reader = reader;
	buffer->data = data;
	buffer->offset = 0;
	buffer->size = 0;
	buffer->len = 0;
	buffer->buffer = reader ? NULL : data;
	return buffer;
}
Пример #10
0
int su_clambda(su_state *s, su_nativefunc f) {
	value_t v;
	int id = s->msi->num_c_lambdas;
	su_assert(s, s->main_state == s, MAIN_STATE_ONLY_MSG);
	s->msi->c_lambdas = (value_t*)su_allocate(s, s->msi->c_lambdas, sizeof(value_t) * (++s->msi->num_c_lambdas));
	if (f) {
		v.type = SU_NATIVEFUNC;
		v.obj.nfunc = f;
		s->msi->c_lambdas[id] = v;
	} else {
		s->msi->c_lambdas[id] = *STK(-1);
		s->stack_top--;
	}
	return id;
}
Пример #11
0
static const_string_t *read_string(su_state *s, reader_buffer_t *buffer) {
	const_string_t *str;
	unsigned size;

	if (buffer_read(s, buffer, &size, sizeof(unsigned)))
		return NULL;

	str = su_allocate(s, NULL, sizeof(unsigned) + size + 1);
	if (buffer_read(s, buffer, str->str, size))
		return NULL;

	str->size = size;
	str->str[size] = '\0';
	return str;
}
Пример #12
0
int su_load(su_state *s, su_reader reader, void *data) {
	prototype_t *prot = su_allocate(s, NULL, sizeof(prototype_t));
	reader_buffer_t *buffer = buffer_open(s, reader, data);

	if (verify_header(s, buffer)) {
		buffer_close(s, buffer);
		return -1;
	}

	if (read_prototype(s, buffer, prot)) {
		buffer_close(s, buffer);
		return -1;
	}

	buffer_close(s, buffer);
	gc_insert_object(s, &prot->gc, PROTOTYPE);
	lambda(s, prot, -1);
	return 0;
}
Пример #13
0
static void free_prot(su_state *s, prototype_t *prot) {
	int i;
	su_allocate(s, prot->inst, 0);
	su_allocate(s, prot->lineinf, 0);
	su_allocate(s, prot->upvalues, 0);
	
	for (i = 0; i < prot->num_const; i++) {
		if (prot->constants[i].id == CSTRING)
			su_allocate(s, prot->constants[i].obj.str, 0);
	}
	su_allocate(s, prot->constants, 0);
	
	for (i = 0; i < prot->num_prot; i++)
		free_prot(s, &prot->prot[i]);
	su_allocate(s, prot->prot, 0);
}
Пример #14
0
    int su_compile(su_state *s, const char *code, const char *name, char **inline_c, char **result, size_t *size) {
        const char *tmp;
        size_t buffer_size;
        lua_State *L = lua_open();
        su_state *sc = su_init(su_allocator(s));
        su_libinit(sc);
        ___saurus(sc);

        luaL_openlibs(L);
        luaopen_writebin(L);

        if (luaL_loadstring(L, compiler_code)) {
            *result = dup(s, lua_tostring(L, -1));
            if (size) *size = strlen(*result);
            lua_close(L);
            su_close(sc);
            return -1;
        }

        if (lua_pcall(L, 0, 0, 0)) {
            lua_getglobal(L, "saurus_error");
            if (lua_isnil(L, -1))
                lua_pop(L, 1);
            *result = dup(s, lua_tostring(L, -1));
            if (size) *size = strlen(*result);
            lua_close(L);
            su_close(sc);
            return -2;
        }

        lua_getglobal(L, "repl");
        lua_pushstring(L, code);
        lua_pushstring(L, name ? name : "?");
        if (lua_pcall(L, 2, 1, 0)) {
            lua_getglobal(L, "saurus_error");
            if (lua_isnil(L, -1)) {
                lua_pop(L, 1);
                *result = dup(s, lua_tostring(L, -1));
            } else {
                *result = dup(s, lua_tostring(L, -1));
            }
            if (size) *size = strlen(*result);
            lua_close(L);
            su_close(sc);
            return -3;
        }

        tmp = lua_tolstring(L, -1, &buffer_size);
        *result = (char*)su_allocate(s, NULL, buffer_size);
        memcpy(*result, tmp, buffer_size);
        if (size) *size = buffer_size;

        if (inline_c) {
            lua_getglobal(L, "c_code");
            if (lua_isnil(L, -1))
                tmp = lua_tostring(L, -1);
            *inline_c = (char*)su_allocate(s, NULL, strlen(tmp) + 1);
            strcpy(*inline_c, tmp);
        }

        lua_close(L);
        su_close(sc);
        return 0;
    }
Пример #15
0
int read_prototype(su_state *s, reader_buffer_t *buffer, prototype_t *prot) {
	unsigned i;
	memset(prot, 0, sizeof(prototype_t));

	assert(sizeof(unsigned) == 4);
	assert(sizeof(instruction_t) == 4);

	READ(&prot->num_inst, sizeof(unsigned));
	prot->inst = su_allocate(s, NULL, sizeof(instruction_t) * prot->num_inst);
	for (i = 0; i < prot->num_inst; i++)
		READ(&prot->inst[i], sizeof(instruction_t));

	READ(&prot->num_const, sizeof(unsigned));
	prot->constants = su_allocate(s, NULL, sizeof(const_t) * prot->num_const);
	for (i = 0; i < prot->num_const; i++) {
		READ(&prot->constants[i].id, sizeof(char));
		switch (prot->constants[i].id) {
			case CSTRING:
				prot->constants[i].obj.str = read_string(s, buffer);
				if (!prot->constants[i].obj.str)
					goto error;
				break;
			case CNUMBER:
				READ(&prot->constants[i].obj.num, sizeof(double));
				break;
			case CTRUE:
			case CFALSE:
			case CNIL:
				break;
			default:
				assert(0);
		}
	}

	READ(&prot->num_ups, sizeof(unsigned));
	prot->upvalues = su_allocate(s, NULL, sizeof(upvalue_t) * prot->num_ups);
	for (i = 0; i < prot->num_ups; i++)
		READ(&prot->upvalues[i], sizeof(upvalue_t));

	READ(&prot->num_prot, sizeof(unsigned));
	prot->prot = su_allocate(s, NULL, sizeof(prototype_t) * prot->num_prot);
	for (i = 0; i < prot->num_prot; i++) {
		if (read_prototype(s, buffer, &prot->prot[i]))
			goto error;
	}

	prot->name = read_string(s, buffer);
	if (!prot->name)
		goto error;

	READ(&prot->num_lineinf, sizeof(unsigned));
	prot->lineinf = su_allocate(s, NULL, sizeof(int) * prot->num_lineinf);
	for (i = 0; i < prot->num_lineinf; i++)
		READ(&prot->lineinf[i], sizeof(unsigned));

	return 0;

error:
	/* TODO: Deleate the rest of the objects. */
	return -1;
}
Пример #16
0
void su_string_ch(su_state *s, char ch) {
	assert(s->string_builder);
	s->string_builder = (string_t*)su_allocate(s, (void*)s->string_builder, sizeof(string_t) + (++s->string_builder->size));
	s->string_builder->str[s->string_builder->size - 1] = ch;
}
Пример #17
0
 static char *dup(su_state *s, const char *str) {
     char *tmp = (char*)su_allocate(s, NULL, strlen(str) + 1);
     strcpy(tmp, str);
     return tmp;
 }