Skip to content

Commit 07222dd

Browse files
committed
---
yaml --- r: 490 b: refs/heads/master c: f307688 h: refs/heads/master v: v3
1 parent 8e2de98 commit 07222dd

File tree

5 files changed

+142
-24
lines changed

5 files changed

+142
-24
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 8e02a2bcb5f8d3dfe03816fed53c51f0a5500f71
2+
refs/heads/master: f307688bf44404b371b91b3b2a67048088695fe1

trunk/src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
477477
lib-deque.rs \
478478
lib-map.rs \
479479
lib-rand.rs \
480+
lib-vec-str-conversions.rs \
480481
linear-for-loop.rs \
481482
list.rs \
482483
many.rs \

trunk/src/lib/_str.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import rustrt.sbuf;
22

3+
import std._vec.rustrt.vbuf;
4+
35
native "rust" mod rustrt {
46
type sbuf;
57
fn str_buf(str s) -> sbuf;
68
fn str_byte_len(str s) -> uint;
79
fn str_alloc(uint n_bytes) -> str;
10+
fn str_from_vec(vec[u8] b) -> str;
811
fn refcount[T](str s) -> uint;
912
}
1013

@@ -40,9 +43,33 @@ fn buf(str s) -> sbuf {
4043
ret rustrt.str_buf(s);
4144
}
4245

43-
fn bytes(&str s) -> vec[u8] {
44-
fn ith(str s, uint i) -> u8 {
45-
ret s.(i);
46+
fn bytes(str s) -> vec[u8] {
47+
/* FIXME (issue #58):
48+
* Should be...
49+
*
50+
* fn ith(str s, uint i) -> u8 {
51+
* ret s.(i);
52+
* }
53+
* ret _vec.init_fn[u8](bind ith(s, _), byte_len(s));
54+
*
55+
* but we do not correctly decrement refcount of s when
56+
* the binding dies, so we have to do this manually.
57+
*/
58+
let uint n = _str.byte_len(s);
59+
let vec[u8] v = _vec.alloc[u8](n);
60+
let uint i = 0u;
61+
while (i < n) {
62+
v += vec(s.(i));
63+
i += 1u;
4664
}
47-
ret _vec.init_fn[u8](bind ith(s, _), _str.byte_len(s));
65+
ret v;
66+
}
67+
68+
fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
69+
ret rustrt.str_from_vec(v);
70+
}
71+
72+
fn refcount(str s) -> uint {
73+
// -1 because calling this function incremented the refcount.
74+
ret rustrt.refcount[u8](s) - 1u;
4875
}

trunk/src/rt/rust_builtin.cpp

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,6 @@
22
#include "rust_internal.h"
33

44
/* Native builtins. */
5-
extern "C" CDECL rust_str*
6-
str_alloc(rust_task *task, size_t n_bytes)
7-
{
8-
rust_dom *dom = task->dom;
9-
size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
10-
void *mem = dom->malloc(alloc);
11-
if (!mem) {
12-
task->fail(2);
13-
return NULL;
14-
}
15-
rust_str *st = new (mem) rust_str(dom, alloc, 1, (uint8_t const *)"");
16-
return st;
17-
}
185

196
extern "C" CDECL rust_str*
207
last_os_error(rust_task *task) {
@@ -109,6 +96,48 @@ vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts)
10996
return vec;
11097
}
11198

99+
extern "C" CDECL void *
100+
vec_buf(rust_task *task, type_desc *ty, rust_vec *v, size_t offset)
101+
{
102+
return (void *)&v->data[ty->size * offset];
103+
}
104+
105+
extern "C" CDECL size_t
106+
vec_len(rust_task *task, type_desc *ty, rust_vec *v)
107+
{
108+
return v->fill / ty->size;
109+
}
110+
111+
/* Helper for str_alloc and str_from_vec. Returns NULL as failure. */
112+
static rust_str *
113+
str_alloc_with_data(rust_task *task,
114+
size_t n_bytes,
115+
size_t fill,
116+
uint8_t const *d)
117+
{
118+
rust_dom *dom = task->dom;
119+
size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
120+
void *mem = dom->malloc(alloc);
121+
if (!mem)
122+
return NULL;
123+
rust_str *st = new (mem) rust_str(dom, alloc, fill, d);
124+
return st;
125+
}
126+
127+
extern "C" CDECL rust_str*
128+
str_alloc(rust_task *task, size_t n_bytes)
129+
{
130+
rust_str *st = str_alloc_with_data(task,
131+
n_bytes + 1, // +1 to fit at least ""
132+
1,
133+
(uint8_t const *)"");
134+
if (!st) {
135+
task->fail(2);
136+
return NULL;
137+
}
138+
return st;
139+
}
140+
112141
extern "C" CDECL char const *
113142
str_buf(rust_task *task, rust_str *s)
114143
{
@@ -121,17 +150,37 @@ str_byte_len(rust_task *task, rust_str *s)
121150
return s->fill - 1; // -1 for the '\0' terminator.
122151
}
123152

124-
extern "C" CDECL void *
125-
vec_buf(rust_task *task, type_desc *ty, rust_vec *v, size_t offset)
153+
extern "C" CDECL rust_str *
154+
str_from_vec(rust_task *task, rust_vec *v)
126155
{
127-
return (void *)&v->data[ty->size * offset];
156+
rust_str *st =
157+
str_alloc_with_data(task,
158+
v->fill + 1, // +1 to fit at least '\0'
159+
v->fill,
160+
v->fill ? (uint8_t const *)v->data : NULL);
161+
if (!st) {
162+
task->fail(2);
163+
return NULL;
164+
}
165+
st->data[st->fill++] = '\0';
166+
return st;
128167
}
129168

130-
extern "C" CDECL size_t
131-
vec_len(rust_task *task, type_desc *ty, rust_vec *v)
169+
/*
170+
extern "C" CDECL rust_str*
171+
str_alloc(rust_task *task, size_t n_bytes)
132172
{
133-
return v->fill / ty->size;
173+
rust_dom *dom = task->dom;
174+
size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes);
175+
void *mem = dom->malloc(alloc);
176+
if (!mem) {
177+
task->fail(2);
178+
return NULL;
179+
}
180+
rust_str *st = new (mem) rust_str(dom, alloc, 1, (uint8_t const *)"");
181+
return st;
134182
}
183+
*/
135184

136185
extern "C" CDECL void *
137186
rand_new(rust_task *task)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// -*- rust -*-
2+
3+
use std;
4+
import std._str;
5+
import std._vec;
6+
7+
fn test_simple() {
8+
let str s1 = "All mimsy were the borogoves";
9+
10+
/*
11+
* FIXME from_bytes(vec[u8] v) has constraint is_utf(v), which is
12+
* unimplemented and thereby just fails. This doesn't stop us from
13+
* using from_bytes for now since the constraint system isn't fully
14+
* working, but we should implement is_utf8 before that happens.
15+
*/
16+
17+
let vec[u8] v = _str.bytes(s1);
18+
let str s2 = _str.from_bytes(v);
19+
20+
let uint i = 0u;
21+
let uint n1 = _str.byte_len(s1);
22+
let uint n2 = _vec.len[u8](v);
23+
24+
check (n1 == n2);
25+
26+
while (i < n1) {
27+
let u8 a = s1.(i);
28+
let u8 b = s2.(i);
29+
log a;
30+
log b;
31+
check (a == b);
32+
i += 1u;
33+
}
34+
35+
log "refcnt is";
36+
log _str.refcount(s1);
37+
}
38+
39+
fn main() {
40+
test_simple();
41+
}

0 commit comments

Comments
 (0)