ToDo:
http://d.hatena.ne.jp/Gimite/20080802/1217647596
の予想は正しげ。
JSString *
js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
{
if (!JSSTRING_IS_MUTABLE(left)) {
/* We must copy if left does not own a buffer to realloc. */
s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar));
if (!s)
return NULL;
js_strncpy(s, ls, ln);
ldep = NULL;
} else {
/* We can realloc left's space and make it depend on our result. */
JS_ASSERT(JSSTRING_IS_FLAT(left));
// これ!
s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar));
if (!s)
return NULL;
/* Take care: right could depend on left! */
lrdist = (size_t)(rs - ls);
if (lrdist < ln)
rs = s + lrdist;
left->u.chars = ls = s;
ldep = left;
}
js_strncpy(s + ln, rs, rn);
n = ln + rn;
s[n] = 0;
str = js_NewString(cx, s, n);
if (!str) {
/* Out of memory: clean up any space we (re-)allocated. */
} else {
JSFLATSTR_SET_MUTABLE(str);
/* Morph left into a dependent prefix if we realloc'd its buffer. */
if (ldep) {
JSPREFIX_INIT(ldep, str, ln);
}
}
return str;
}
(14:34)
Ruby の String ってたしかゼロ終端かつ文字数知ってる みたいな感じだったっけ。 となると + にこの最適化はできないだろう。 C 拡張書かせること考えると正しい判断なんだろう
(14:46)
(14:57)
| 前 | 2008年 8月 |
次 | ||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 | ||||||
全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。
おお、わざわざありがとうございます。Rubyに適用できないのはそのとおりだと思います。
なんか RString はゼロ終端してるけど保証はしてないとか教えてもらいました。将来的には JS 的なことやってもいいのかも。
ゼロ終端しないという風にしてしまうと結構な量の拡張ライブラリが動かなくなりそうな。自分はてっきり保証されているものだと思っていました。
StringValueCStr 使うのがグッドプラクティスらしいです
StringValuePtr ではだめなんでしょうか。 StringValueCStr だと途中に Null 文字があったりするときに例外が投げられてしまうのですが。
途中に Null 文字があるような文字列を扱う場合は、何にせよ文字の長さを意識する必要があるので、ゼロ終端である必要はないってことか。 (多分) 自己解決しました。
星さんの理解で正しいです。
なおその辺の仕様については1.9のREADME.EXT(.ja)に明記されています。
ありがとうございます。