<commit_before>#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"

int js_getlength(js_State *J, int idx)
{
	int len;
	js_getproperty(J, idx, "length");
	len = js_tointeger(J, -1);
	js_pop(J, 1);
	return len;
}

void js_setlength(js_State *J, int idx, int len)
{
	js_pushnumber(J, len);
	js_setproperty(J, idx < 0 ? idx - 1 : idx, "length");
}

int js_hasindex(js_State *J, int idx, int i)
{
	char buf[32];
	return js_hasproperty(J, idx, js_itoa(buf, i));
}

void js_getindex(js_State *J, int idx, int i)
{
	char buf[32];
	js_getproperty(J, idx, js_itoa(buf, i));
}

void js_setindex(js_State *J, int idx, int i)
{
	char buf[32];
	js_setproperty(J, idx, js_itoa(buf, i));
}

void js_delindex(js_State *J, int idx, int i)
{
	char buf[32];
	js_delproperty(J, idx, js_itoa(buf, i));
}

static void jsB_new_Array(js_State *J)
{
	int i, top = js_gettop(J);

	js_newarray(J);

	if (top == 2) {
		if (js_isnumber(J, 1)) {
			js_copy(J, 1);
			js_setproperty(J, -2, "length");
		} else {
			js_copy(J, 1);
			js_setindex(J, -2, 0);
		}
	} else {
		for (i = 1; i < top; ++i) {
			js_copy(J, i);
			js_setindex(J, -2, i - 1);
		}
	}
}

static void Ap_concat(js_State *J)
{
	int i, top = js_gettop(J);
	int n, k, len;

	js_newarray(J);
	n = 0;

	for (i = 0; i < top; ++i) {
		js_copy(J, i);
		if (js_isarray(J, -1)) {
			len = js_getlength(J, -1);
			for (k = 0; k < len; ++k)
				if (js_hasindex(J, -1, k))
					js_setindex(J, -3, n++);
			js_pop(J, 1);
		} else {
			js_setindex(J, -2, n++);
		}
	}
}

static void Ap_join(js_State *J)
{
	char * volatile out = NULL;
	const char *sep;
	const char *r;
	int seplen;
	int k, n, len;

	len = js_getlength(J, 0);

	if (js_isdefined(J, 1)) {
		sep = js_tostring(J, 1);
		seplen = strlen(sep);
	} else {
		sep = ",";
		seplen = 1;
	}

	if (len <= 0) {
		js_pushliteral(J, "");
		return;
	}

	if (js_try(J)) {
		js_free(J, out);
		js_throw(J);
	}

	n = 1;
	for (k = 0; k < len; ++k) {
		js_getindex(J, 0, k);
		if (js_isundefined(J, -1) || js_isnull(J, -1))
			r = "";
		else
			r = js_tostring(J, -1);
		n += strlen(r);

		if (k == 0) {
			if (n > JS_STRLIMIT)
				js_rangeerror(J, "invalid string length");
			out = js_malloc(J, (int)n);
			strcpy(out, r);
		} else {
			n += seplen;
			if (n > JS_STRLIMIT)
				js_rangeerror(J, "invalid string length");
			out = js_realloc(J, out, (int)n);
			strcat(out, sep);
			strcat(out, r);
		}

		js_pop(J, 1);
	}

	js_pushstring(J, out);
	js_endtry(J);
	js_free(J, out);
}

static void Ap_pop(js_State *J)
{
	int n;
<commit_msg>array join: avoid strcat, speedup from O(N^2) to O(N)<commit_after>#include "jsi.h"
#include "jsvalue.h"
#include "jsbuiltin.h"

int js_getlength(js_State *J, int idx)
{
	int len;
	js_getproperty(J, idx, "length");
	len = js_tointeger(J, -1);
	js_pop(J, 1);
	return len;
}

void js_setlength(js_State *J, int idx, int len)
{
	js_pushnumber(J, len);
	js_setproperty(J, idx < 0 ? idx - 1 : idx, "length");
}

int js_hasindex(js_State *J, int idx, int i)
{
	char buf[32];
	return js_hasproperty(J, idx, js_itoa(buf, i));
}

void js_getindex(js_State *J, int idx, int i)
{
	char buf[32];
	js_getproperty(J, idx, js_itoa(buf, i));
}

void js_setindex(js_State *J, int idx, int i)
{
	char buf[32];
	js_setproperty(J, idx, js_itoa(buf, i));
}

void js_delindex(js_State *J, int idx, int i)
{
	char buf[32];
	js_delproperty(J, idx, js_itoa(buf, i));
}

static void jsB_new_Array(js_State *J)
{
	int i, top = js_gettop(J);

	js_newarray(J);

	if (top == 2) {
		if (js_isnumber(J, 1)) {
			js_copy(J, 1);
			js_setproperty(J, -2, "length");
		} else {
			js_copy(J, 1);
			js_setindex(J, -2, 0);
		}
	} else {
		for (i = 1; i < top; ++i) {
			js_copy(J, i);
			js_setindex(J, -2, i - 1);
		}
	}
}

static void Ap_concat(js_State *J)
{
	int i, top = js_gettop(J);
	int n, k, len;

	js_newarray(J);
	n = 0;

	for (i = 0; i < top; ++i) {
		js_copy(J, i);
		if (js_isarray(J, -1)) {
			len = js_getlength(J, -1);
			for (k = 0; k < len; ++k)
				if (js_hasindex(J, -1, k))
					js_setindex(J, -3, n++);
			js_pop(J, 1);
		} else {
			js_setindex(J, -2, n++);
		}
	}
}

static void Ap_join(js_State *J)
{
	char * volatile out = NULL;
	const char *sep;
	const char *r;
	int seplen;
	int k, n, len, outlen, rlen;

	len = js_getlength(J, 0);

	if (js_isdefined(J, 1)) {
		sep = js_tostring(J, 1);
		seplen = strlen(sep);
	} else {
		sep = ",";
		seplen = 1;
	}

	if (len <= 0) {
		js_pushliteral(J, "");
		return;
	}

	if (js_try(J)) {
		js_free(J, out);
		js_throw(J);
	}

	n = 1;
	for (k = 0; k < len; ++k) {
		js_getindex(J, 0, k);
		if (js_isundefined(J, -1) || js_isnull(J, -1))
			r = "";
		else
			r = js_tostring(J, -1);
		outlen = n - 1;
		rlen = strlen(r);
		n += rlen;

		if (k == 0) {
			if (n > JS_STRLIMIT)
				js_rangeerror(J, "invalid string length");
			out = js_malloc(J, (int)n);
			memcpy(out, r, rlen + 1);
		} else {
			n += seplen;
			if (n > JS_STRLIMIT)
				js_rangeerror(J, "invalid string length");
			out = js_realloc(J, out, (int)n);
			memcpy(out + outlen, sep, seplen);
			memcpy(out + outlen + seplen, r, rlen + 1);
		}

		js_pop(J, 1);
	}

	js_pushstring(J, out);
	js_endtry(J);
	js_free(J, out);
}

static void Ap_pop(js_State *J)
{
	int n;

{'fraction_non_alphanumeric': 0.19064191802010827, 'fraction_numerical': 0.017788089713843776, 'mean_word_length': 3.2159739201303994, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2386012', 'n_tokens_mistral': 2734, 'n_tokens_neox': 2501, 'n_words': 609}