📄 b_array.c
字号:
JS_COPY (&n->u.varray->data[old_len + i], &args[i + 1]);
JS_COPY (result_return, &args[i]);
}
/* ********************************************************************** */
else if (method == ctx->s_reverse)
{
if (args->u.vinteger != 0)
goto argument_error;
for (i = 0; i < n->u.varray->length / 2; i++)
{
JSNode tmp;
JS_COPY (&tmp, &n->u.varray->data[i]);
JS_COPY (&n->u.varray->data[i],
&n->u.varray->data[n->u.varray->length - i - 1]);
JS_COPY (&n->u.varray->data[n->u.varray->length - i - 1], &tmp);
}
}
/* ********************************************************************** */
else if (method == ctx->s_shift)
{
if (args->u.vinteger != 0)
goto argument_error;
if (n->u.varray->length == 0)
result_return->type = JS_UNDEFINED;
else
{
JS_COPY (result_return, &n->u.varray->data[0]);
memmove (&n->u.varray->data[0], &n->u.varray->data[1],
(n->u.varray->length - 1) * sizeof (JSNode));
n->u.varray->length--;
}
}
/* ********************************************************************** */
else if (method == ctx->s_slice)
{
int start, end;
if (args->u.vinteger < 1 || args->u.vinteger > 2)
goto argument_error;
if (args[1].type != JS_INTEGER)
goto argument_type_error;
start = args[1].u.vinteger;
if (args->u.vinteger == 2)
{
if (args[2].type != JS_INTEGER)
goto argument_type_error;
end = args[2].u.vinteger;
}
else
end = n->u.varray->length;
if (end < 0)
end += n->u.varray->length;
if (end < 0)
end = start;
js_vm_make_array (vm, result_return, end - start);
/* Copy items. */
for (i = 0; i < end - start; i++)
JS_COPY (&result_return->u.varray->data[i],
&n->u.varray->data[start + i]);
}
/* ********************************************************************** */
else if (method == ctx->s_splice)
{
unsigned int new_length;
unsigned int old_length;
int delta;
if (args->u.vinteger < 2)
goto argument_error;
if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER)
goto argument_type_error;
if (args[2].u.vinteger == 0 && args->u.vinteger == 2)
/* No deletions: must specify at least one item to insert. */
goto argument_error;
old_length = new_length = n->u.varray->length;
if (args[1].u.vinteger < new_length)
{
if (args[2].u.vinteger > new_length - args[1].u.vinteger)
{
args[2].u.vinteger = new_length - args[1].u.vinteger;
new_length = args[1].u.vinteger;
}
else
new_length -= args[2].u.vinteger;
}
else
{
new_length = args[1].u.vinteger;
args[2].u.vinteger = 0;
}
new_length += args->u.vinteger - 2;
if (new_length > n->u.varray->length)
js_vm_expand_array (vm, n, new_length);
else
/* Cut the array. */
n->u.varray->length = new_length;
/* Do the stuffs we must do. */
/* Create the result array. */
if (args[2].u.vinteger == 0)
result_return->type = JS_UNDEFINED;
else
{
js_vm_make_array (vm, result_return, args[2].u.vinteger);
for (i = 0; i < args[2].u.vinteger; i++)
JS_COPY (&result_return->u.varray->data[i],
&n->u.varray->data[args[1].u.vinteger + i]);
}
/* Delete and move. */
delta = args->u.vinteger - 2 - args[2].u.vinteger;
memmove (&n->u.varray->data[args[1].u.vinteger + args[2].u.vinteger
+ delta],
&n->u.varray->data[args[1].u.vinteger + args[2].u.vinteger],
(old_length - (args[1].u.vinteger + args[2].u.vinteger))
* sizeof (JSNode));
/* Insert. */
for (i = 0; i < args->u.vinteger - 2; i++)
JS_COPY (&n->u.varray->data[args[1].u.vinteger + i], &args[i + 3]);
}
/* ********************************************************************** */
else if (method == ctx->s_sort)
{
MergesortCompFunc func;
ArraySortCtx array_sort_ctx;
void *func_ctx = NULL; /* Initialized to keep compiler quiet. */
if (args->u.vinteger == 0)
{
func = sort_default_cmp_func;
func_ctx = vm;
}
else if (args->u.vinteger == 1)
{
if (args[1].type != JS_FUNC && args[1].type != JS_BUILTIN)
goto argument_type_error;
func = sort_js_cmp_func;
/* Init context. */
array_sort_ctx.vm = vm;
array_sort_ctx.func = &args[1];
/* Init the argc part of the argument vector here. */
array_sort_ctx.argv[0].type = JS_INTEGER;
array_sort_ctx.argv[0].u.vinteger = 3;
func_ctx = &array_sort_ctx;
}
else
goto argument_error;
mergesort_r (n->u.varray->data, n->u.varray->length, sizeof (JSNode),
func, func_ctx);
}
/* ********************************************************************** */
else if (method == ctx->s_unshift)
{
int old_len;
if (args->u.vinteger == 0)
goto argument_error;
old_len = n->u.varray->length;
js_vm_expand_array (vm, n, n->u.varray->length + args->u.vinteger);
memmove (&n->u.varray->data[args->u.vinteger], n->u.varray->data,
old_len * sizeof (JSNode));
for (i = 0; i < args->u.vinteger; i++)
JS_COPY (&n->u.varray->data[i], &args[args->u.vinteger - i]);
result_return->type = JS_INTEGER;
result_return->u.vinteger = n->u.varray->length;
}
/* ********************************************************************** */
else
return JS_PROPERTY_UNKNOWN;
return JS_PROPERTY_FOUND;
/*
* Error handling.
*/
argument_error:
sprintf (vm->error, "Array.%s(): illegal amount of arguments",
js_vm_symname (vm, method));
js_vm_error (vm);
argument_type_error:
sprintf (vm->error, "Array.%s(): illegal argument",
js_vm_symname (vm, method));
js_vm_error (vm);
/* NOTREACHED */
return 0;
}
/* Property proc. */
static int
property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
void *instance_context, JSSymbol property, int set, JSNode *node)
{
ArrayCtx *ctx = builtin_info->obj_context;
JSNode *n = instance_context;
if (property == ctx->s_length)
{
if (set)
goto immutable;
node->type = JS_INTEGER;
node->u.vinteger = n->u.varray->length;
}
else
{
if (!set)
node->type = JS_UNDEFINED;
return JS_PROPERTY_UNKNOWN;
}
return JS_PROPERTY_FOUND;
/*
* Error handling.
*/
immutable:
sprintf (vm->error, "Array.%s: immutable property",
js_vm_symname (vm, property));
js_vm_error (vm);
/* NOTREACHED */
return 0;
}
/* New proc. */
static void
new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
JSNode *result_return)
{
int i;
if (args->u.vinteger == 1 && args[1].type == JS_INTEGER)
{
/* Create a fixed length array. */
js_vm_make_array (vm, result_return, args[1].u.vinteger);
}
else
{
if (args->u.vinteger < 0)
/* We are called from the array initializer. */
args->u.vinteger = -args->u.vinteger;
js_vm_make_array (vm, result_return, args->u.vinteger);
for (i = 0; i < args->u.vinteger; i++)
JS_COPY (&result_return->u.varray->data[i], &args[i + 1]);
}
/* Set the [[Prototype]] and [[Class]] properties. */
/* XXX 15.7.2.1 */
}
/*
* Global functions.
*/
void
js_builtin_Array (JSVirtualMachine *vm)
{
ArrayCtx *ctx;
JSNode *n;
JSBuiltinInfo *info;
ctx = js_calloc (vm, 1, sizeof (*ctx));
ctx->s_concat = js_vm_intern (vm, "concat");
ctx->s_join = js_vm_intern (vm, "join");
ctx->s_pop = js_vm_intern (vm, "pop");
ctx->s_push = js_vm_intern (vm, "push");
ctx->s_reverse = js_vm_intern (vm, "reverse");
ctx->s_shift = js_vm_intern (vm, "shift");
ctx->s_slice = js_vm_intern (vm, "slice");
ctx->s_splice = js_vm_intern (vm, "splice");
ctx->s_sort = js_vm_intern (vm, "sort");
ctx->s_unshift = js_vm_intern (vm, "unshift");
ctx->s_length = js_vm_intern (vm, "length");
info = js_vm_builtin_info_create (vm);
vm->prim[JS_ARRAY] = info;
info->global_method_proc = global_method;
info->method_proc = method;
info->property_proc = property;
info->new_proc = new_proc;
info->obj_context = ctx;
info->obj_context_delete = js_free;
/* Define it. */
n = &vm->globals[js_vm_intern (vm, "Array")];
js_vm_builtin_create (vm, n, info, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -