static void O_create(js_State *J) { js_Object *obj; js_Object *proto; js_Object *props; js_Property *ref; if (js_isobject(J, 1)) proto = js_toobject(J, 1); else if (js_isnull(J, 1)) proto = NULL; else js_typeerror(J, "not an object or null"); obj = jsV_newobject(J, JS_COBJECT, proto); js_pushobject(J, obj); if (js_isdefined(J, 2)) { if (!js_isobject(J, 2)) js_typeerror(J, "not an object"); props = js_toobject(J, 2); for (ref = props->head; ref; ref = ref->next) { if (!(ref->atts & JS_DONTENUM)) { if (ref->value.type != JS_TOBJECT) js_typeerror(J, "not an object"); ToPropertyDescriptor(J, obj, ref->name, ref->value.u.object); } } } }
static void Sp_split_regexp(js_State *J) { js_Regexp *re; const char *text; unsigned int limit, len, k; const char *p, *a, *b, *c, *e; Resub m; text = js_tostring(J, 0); re = js_toregexp(J, 1); limit = js_isdefined(J, 2) ? js_touint32(J, 2) : 1 << 30; js_newarray(J); len = 0; e = text + strlen(text); /* splitting the empty string */ if (e == 0) { if (js_regexec(re->prog, text, &m, 0)) { if (len == limit) return; js_pushliteral(J, ""); js_setindex(J, -2, 0); } return; } p = a = text; while (a < e) { if (js_regexec(re->prog, a, &m, a > text ? REG_NOTBOL : 0)) break; /* no match */ b = m.sub[0].sp; c = m.sub[0].ep; /* empty string at end of last match */ if (b == p) { ++a; continue; } if (len == limit) return; js_pushlstring(J, p, b - p); js_setindex(J, -2, len++); for (k = 1; k < m.nsub; ++k) { if (len == limit) return; js_pushlstring(J, m.sub[k].sp, m.sub[k].ep - m.sub[k].sp); js_setindex(J, -2, len++); } a = p = c; } if (len == limit) return; js_pushstring(J, p); js_setindex(J, -2, len); }
static void Ap_join(js_State *J) { char * volatile out = NULL; const char *sep; const char *r; unsigned int seplen; unsigned 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) { out = js_malloc(J, n); strcpy(out, r); } else { n += seplen; out = realloc(out, n); strcat(out, sep); strcat(out, r); } js_pop(J, 1); } js_pushstring(J, out); js_endtry(J); js_free(J, out); }
static void Sp_lastIndexOf(js_State *J) { const char *haystack = js_tostring(J, 0); const char *needle = js_tostring(J, 1); int pos = js_isdefined(J, 2) ? js_tointeger(J, 2) : strlen(haystack); int len = strlen(needle); int k = 0, last = -1; Rune rune; while (*haystack && k <= pos) { if (!strncmp(haystack, needle, len)) last = k; haystack += chartorune(&rune, haystack); ++k; } js_pushnumber(J, last); }
int eval_print(js_State *J, const char *source) { if (js_ploadstring(J, "[string]", source)) { fprintf(stderr, "%s\n", js_tostring(J, -1)); js_pop(J, 1); return 1; } js_pushglobal(J); if (js_pcall(J, 0)) { fprintf(stderr, "%s\n", js_tostring(J, -1)); js_pop(J, 1); return 1; } if (js_isdefined(J, -1)) printf("%s\n", js_tostring(J, -1)); js_pop(J, 1); return 0; }
static int eval_print(js_State *J, const char *source) { if (js_ploadstring(J, "[stdin]", source)) { fprintf(stderr, "%s\n", js_trystring(J, -1, "Error")); js_pop(J, 1); return 1; } js_pushundefined(J); if (js_pcall(J, 0)) { fprintf(stderr, "%s\n", js_trystring(J, -1, "Error")); js_pop(J, 1); return 1; } if (js_isdefined(J, -1)) { printf("%s\n", js_tryrepr(J, -1, "can't convert to string")); } js_pop(J, 1); return 0; }
static void jsB_parseInt(js_State *J) { const char *s = js_tostring(J, 1); double radix = js_isdefined(J, 2) ? js_tonumber(J, 2) : 10; char *e; double n; while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s; if (radix == 0) radix = 10; if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { s += 2; radix = 16; } n = strtol(s, &e, radix); if (s == e) js_pushnumber(J, NAN); else js_pushnumber(J, n); }
static void Sp_substring(js_State *J) { const char *str = js_tostring(J, 0); const char *ss, *ee; int len = utflen(str); int s = js_tointeger(J, 1); int e = js_isdefined(J, 2) ? js_tointeger(J, 2) : len; s = s < 0 ? 0 : s > len ? len : s; e = e < 0 ? 0 : e > len ? len : e; if (s < e) { ss = js_utfidxtoptr(str, s); ee = js_utfidxtoptr(ss, e - s); } else { ss = js_utfidxtoptr(str, e); ee = js_utfidxtoptr(ss, s - e); } js_pushlstring(J, ss, ee - ss); }
static void Ap_slice(js_State *J) { unsigned int len, s, e, n; double sv, ev; js_newarray(J); len = js_getlength(J, 0); sv = js_tointeger(J, 1); ev = js_isdefined(J, 2) ? js_tointeger(J, 2) : len; if (sv < 0) sv = sv + len; if (ev < 0) ev = ev + len; s = sv < 0 ? 0 : sv > len ? len : sv; e = ev < 0 ? 0 : ev > len ? len : ev; for (n = 0; s < e; ++s, ++n) if (js_hasindex(J, 0, s)) js_setindex(J, -2, n); }
static void Ap_lastIndexOf(js_State *J) { int k, len, from; len = js_getlength(J, 0); from = js_isdefined(J, 2) ? js_tointeger(J, 2) : len - 1; if (from > len - 1) from = len - 1; if (from < 0) from = len + from; js_copy(J, 1); for (k = from; k >= 0; --k) { if (js_hasindex(J, 0, k)) { if (js_strictequal(J)) { js_pushnumber(J, k); return; } js_pop(J, 1); } } js_pushnumber(J, -1); }
static void Sp_split_string(js_State *J) { const char *str = js_tostring(J, 0); const char *sep = js_tostring(J, 1); unsigned int limit = js_isdefined(J, 2) ? js_touint32(J, 2) : 1 << 30; unsigned int i, n; js_newarray(J); n = strlen(sep); /* empty string */ if (n == 0) { Rune rune; for (i = 0; *str && i < limit; ++i) { n = chartorune(&rune, str); js_pushlstring(J, str, n); js_setindex(J, -2, i); str += n; } return; } for (i = 0; str && i < limit; ++i) { const char *s = strstr(str, sep); if (s) { js_pushlstring(J, str, s-str); js_setindex(J, -2, i); str = s + n; } else { js_pushstring(J, str); js_setindex(J, -2, i); str = NULL; } } }
static void jsB_Function(js_State *J) { unsigned int i, top = js_gettop(J); js_Buffer *sb = NULL; const char *body; js_Ast *parse; js_Function *fun; /* p1, p2, ..., pn */ if (top > 2) { for (i = 1; i < top - 1; ++i) { if (i > 1) js_putc(J, &sb, ','); js_puts(J, &sb, js_tostring(J, i)); } js_putc(J, &sb, ')'); } /* body */ body = js_isdefined(J, top - 1) ? js_tostring(J, top - 1) : ""; if (js_try(J)) { js_free(J, sb); jsP_freeparse(J); js_throw(J); } parse = jsP_parsefunction(J, "[string]", sb ? sb->s : NULL, body); fun = jsC_compilefunction(J, parse); js_endtry(J); js_free(J, sb); jsP_freeparse(J); js_newfunction(J, fun, J->GE); }
static void jsB_compile(js_State *J) { const char *source = js_tostring(J, 1); const char *filename = js_isdefined(J, 2) ? js_tostring(J, 2) : "[string]"; js_loadstring(J, filename, source); }