V7_PRIVATE void Arr_length(struct v7_val *this_obj, struct v7_val *result) { struct v7_prop *p; v7_init_num(result, 0.0); for (p = this_obj->v.array; p != NULL; p = p->next) { result->v.num += 1.0; } }
static void Str_charCodeAt(struct v7_c_func_arg *cfa) { double idx = cfa->num_args > 0 && cfa->args[0]->type == V7_TYPE_NUM ? cfa->args[0]->v.num : NAN; const struct v7_string *str = &cfa->this_obj->v.str; v7_init_num(cfa->result, NAN); if (!isnan(idx) && cfa->this_obj->type == V7_TYPE_STR && fabs(idx) < str->len) { cfa->result->v.num = ((unsigned char *) str->buf)[(int) idx]; } }
V7_PRIVATE int cmp(const struct v7_val *a, const struct v7_val *b) { int res; double an, bn; const struct v7_string *as, *bs; struct v7_val ta = MKOBJ(0), tb = MKOBJ(0); if (a == NULL || b == NULL) return 1; if ((a->type == V7_TYPE_UNDEF || a->type == V7_TYPE_NULL) && (b->type == V7_TYPE_UNDEF || b->type == V7_TYPE_NULL)) return 0; if (is_num(a) && is_num(b)) { v7_init_num(&ta, a->v.num); v7_init_num(&tb, b->v.num); a = &ta; b = &tb; } if (is_string(a) && is_string(b)) { v7_init_str(&ta, a->v.str.buf, a->v.str.len, 0); v7_init_str(&tb, b->v.str.buf, b->v.str.len, 0); a = &ta; b = &tb; } if (a->type != b->type) return 1; an = a->v.num, bn = b->v.num; as = &a->v.str, bs = &b->v.str; switch (a->type) { case V7_TYPE_NUM: return (isinf(an) && isinf(bn)) || (isnan(an) && isnan(bn)) ? 0 : an - bn; case V7_TYPE_BOOL: return an != bn; case V7_TYPE_STR: res = memcmp(as->buf, bs->buf, as->len < bs->len ? as->len : bs->len); return res != 0 ? res : (int) as->len - (int) bs->len; return as->len != bs->len || memcmp(as->buf, bs->buf, as->len) != 0; default: return (int) (a - b); } }
V7_PRIVATE enum v7_err Number_ctor(struct v7_c_func_arg *cfa) { struct v7_val *obj = cfa->called_as_constructor ? cfa->this_obj : v7_push_new_object(cfa->v7); struct v7_val *arg = cfa->args[0]; v7_init_num(obj, cfa->num_args > 0 ? arg->v.num : 0.0); if (cfa->num_args > 0 && !is_num(arg) && !is_bool(arg)) { if (is_string(arg)) { v7_init_num(obj, strtod(arg->v.str.buf, NULL)); } else { v7_init_num(obj, NAN); } } if (cfa->called_as_constructor) { obj->type = V7_TYPE_OBJ; obj->proto = &s_prototypes[V7_CLASS_NUMBER]; obj->ctor = &s_constructors[V7_CLASS_NUMBER]; } return V7_OK; }
static void Str_indexOf(struct v7_c_func_arg *cfa) { v7_init_num(cfa->result, -1.0); if (cfa->this_obj->type == V7_TYPE_STR && cfa->num_args > 0 && cfa->args[0]->type == V7_TYPE_STR) { int i = cfa->num_args > 1 && cfa->args[1]->type == V7_TYPE_NUM ? (int) cfa->args[1]->v.num : 0; const struct v7_string *a = &cfa->this_obj->v.str, *b = &cfa->args[0]->v.str; // Scan the string, advancing one byte at a time for (; i >= 0 && a->len >= b->len && i <= (int) (a->len - b->len); i++) { if (memcmp(a->buf + i, b->buf, b->len) == 0) { cfa->result->v.num = i; break; } } } }
V7_PRIVATE void Str_length(struct v7_val *this_obj, struct v7_val *arg, struct v7_val *result) { if (NULL == result || arg) return; v7_init_num(result, this_obj->v.str.len); }
static void Str_length(struct v7_val *this_obj, struct v7_val *result) { v7_init_num(result, this_obj->v.str.len); }