suite.c roots
This commit is contained in:
455
source/suite.c
455
source/suite.c
@@ -372,20 +372,23 @@ TEST(object_string_property) {
|
||||
/* GC-SAFE: Uses GC refs to protect objects across allocations */
|
||||
TEST(object_nested) {
|
||||
JSGCRef outer_ref, inner_ref;
|
||||
JS_AddGCRef(ctx, &outer_ref);
|
||||
JS_AddGCRef(ctx, &inner_ref);
|
||||
JS_PushGCRef(ctx, &outer_ref);
|
||||
JS_PushGCRef(ctx, &inner_ref);
|
||||
|
||||
outer_ref.val = JS_NewObject(ctx);
|
||||
inner_ref.val = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, inner_ref.val, "value", JS_NewInt32(ctx, 99));
|
||||
/* Create value first, then read refs after allocation */
|
||||
JSValue v99 = JS_NewInt32(ctx, 99);
|
||||
JS_SetPropertyStr(ctx, inner_ref.val, "value", v99);
|
||||
JS_SetPropertyStr(ctx, outer_ref.val, "inner", inner_ref.val);
|
||||
|
||||
JSValue gotInner = JS_GetPropertyStr(ctx, outer_ref.val, "inner");
|
||||
ASSERT(JS_IsRecord(gotInner));
|
||||
JSValue val = JS_GetPropertyStr(ctx, gotInner, "value");
|
||||
|
||||
JS_DeleteGCRef(ctx, &inner_ref);
|
||||
JS_DeleteGCRef(ctx, &outer_ref);
|
||||
/* Pop in reverse order (LIFO) */
|
||||
JS_PopGCRef(ctx, &inner_ref);
|
||||
JS_PopGCRef(ctx, &outer_ref);
|
||||
|
||||
ASSERT_INT(val, 99);
|
||||
return 1;
|
||||
@@ -394,14 +397,16 @@ TEST(object_nested) {
|
||||
/* GC-SAFE: Uses GC ref to protect object across multiple property sets */
|
||||
TEST(object_many_properties_resize) {
|
||||
JSGCRef obj_ref;
|
||||
JS_AddGCRef(ctx, &obj_ref);
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
|
||||
/* Add many properties to trigger resize */
|
||||
for (int i = 0; i < 100; i++) {
|
||||
char key[16];
|
||||
snprintf(key, sizeof(key), "prop%d", i);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, key, JS_NewInt32(ctx, i * 10));
|
||||
/* Create value first, then read obj_ref.val after allocation */
|
||||
JSValue val = JS_NewInt32(ctx, i * 10);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, key, val);
|
||||
}
|
||||
|
||||
/* Verify all properties */
|
||||
@@ -412,7 +417,7 @@ TEST(object_many_properties_resize) {
|
||||
ASSERT_INT(val, i * 10);
|
||||
}
|
||||
|
||||
JS_DeleteGCRef(ctx, &obj_ref);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -430,7 +435,7 @@ TEST(array_create) {
|
||||
/* GC-SAFE: Uses GC ref for array operations */
|
||||
TEST(array_push_and_length) {
|
||||
JSGCRef arr_ref;
|
||||
JS_AddGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 20));
|
||||
@@ -438,7 +443,7 @@ TEST(array_push_and_length) {
|
||||
|
||||
int64_t len;
|
||||
JS_GetLength(ctx, arr_ref.val, &len);
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(len == 3);
|
||||
return 1;
|
||||
}
|
||||
@@ -446,7 +451,7 @@ TEST(array_push_and_length) {
|
||||
/* GC-SAFE: Uses GC ref for array operations */
|
||||
TEST(array_get_by_index) {
|
||||
JSGCRef arr_ref;
|
||||
JS_AddGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 100));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 200));
|
||||
@@ -455,7 +460,7 @@ TEST(array_get_by_index) {
|
||||
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0);
|
||||
JSValue v1 = JS_GetPropertyUint32(ctx, arr_ref.val, 1);
|
||||
JSValue v2 = JS_GetPropertyUint32(ctx, arr_ref.val, 2);
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
|
||||
ASSERT_INT(v0, 100);
|
||||
ASSERT_INT(v1, 200);
|
||||
@@ -466,17 +471,20 @@ TEST(array_get_by_index) {
|
||||
/* GC-SAFE: Uses GC ref for array operations */
|
||||
TEST(array_set_by_index) {
|
||||
JSGCRef arr_ref;
|
||||
JS_AddGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 0));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 0));
|
||||
|
||||
JS_SetPropertyUint32(ctx, arr_ref.val, 0, JS_NewInt32(ctx, 55));
|
||||
JS_SetPropertyUint32(ctx, arr_ref.val, 1, JS_NewInt32(ctx, 66));
|
||||
/* Create values first, then read arr_ref.val */
|
||||
JSValue v55 = JS_NewInt32(ctx, 55);
|
||||
JS_SetPropertyUint32(ctx, arr_ref.val, 0, v55);
|
||||
JSValue v66 = JS_NewInt32(ctx, 66);
|
||||
JS_SetPropertyUint32(ctx, arr_ref.val, 1, v66);
|
||||
|
||||
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0);
|
||||
JSValue v1 = JS_GetPropertyUint32(ctx, arr_ref.val, 1);
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
|
||||
ASSERT_INT(v0, 55);
|
||||
ASSERT_INT(v1, 66);
|
||||
@@ -486,7 +494,7 @@ TEST(array_set_by_index) {
|
||||
/* GC-SAFE: Uses GC ref for array operations */
|
||||
TEST(array_pop) {
|
||||
JSGCRef arr_ref;
|
||||
JS_AddGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
@@ -497,7 +505,7 @@ TEST(array_pop) {
|
||||
|
||||
int64_t len;
|
||||
JS_GetLength(ctx, arr_ref.val, &len);
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(len == 2);
|
||||
return 1;
|
||||
}
|
||||
@@ -505,23 +513,26 @@ TEST(array_pop) {
|
||||
/* GC-SAFE: Uses GC ref for array operations */
|
||||
TEST(array_out_of_bounds_is_null) {
|
||||
JSGCRef arr_ref;
|
||||
JS_AddGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
|
||||
JSValue val = JS_GetPropertyUint32(ctx, arr_ref.val, 999);
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsNull(val));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* GC-SAFE: Uses GC ref for array operations */
|
||||
TEST(array_mixed_types) {
|
||||
JSGCRef arr_ref;
|
||||
JS_AddGCRef(ctx, &arr_ref);
|
||||
JSGCRef arr_ref, str_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &str_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
/* Create string first, then push - string might trigger GC */
|
||||
str_ref.val = JS_NewString(ctx, "hello");
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 42));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewString(ctx, "hello"));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, str_ref.val);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_TRUE);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NULL);
|
||||
|
||||
@@ -529,7 +540,8 @@ TEST(array_mixed_types) {
|
||||
JSValue v1 = JS_GetPropertyUint32(ctx, arr_ref.val, 1);
|
||||
JSValue v2 = JS_GetPropertyUint32(ctx, arr_ref.val, 2);
|
||||
JSValue v3 = JS_GetPropertyUint32(ctx, arr_ref.val, 3);
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &str_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
|
||||
ASSERT(JS_IsInt(v0));
|
||||
ASSERT(JS_IsText(v1));
|
||||
@@ -540,23 +552,23 @@ TEST(array_mixed_types) {
|
||||
|
||||
TEST(array_many_elements_resize) {
|
||||
JSGCRef arr_ref;
|
||||
JSValue *arr_ptr = JS_AddGCRef(ctx, &arr_ref);
|
||||
*arr_ptr = JS_NewArray(ctx);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
JS_ArrayPush(ctx, arr_ptr, JS_NewInt32(ctx, i));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, i));
|
||||
}
|
||||
JSValue arr = *arr_ptr;
|
||||
JS_DeleteGCRef(ctx, &arr_ref);
|
||||
|
||||
int64_t len;
|
||||
JS_GetLength(ctx, arr, &len);
|
||||
JS_GetLength(ctx, arr_ref.val, &len);
|
||||
ASSERT(len == 1000);
|
||||
|
||||
/* Verify some values */
|
||||
JSValue v0 = JS_GetPropertyUint32(ctx, arr, 0);
|
||||
JSValue v500 = JS_GetPropertyUint32(ctx, arr, 500);
|
||||
JSValue v999 = JS_GetPropertyUint32(ctx, arr, 999);
|
||||
JSValue v0 = JS_GetPropertyUint32(ctx, arr_ref.val, 0);
|
||||
JSValue v500 = JS_GetPropertyUint32(ctx, arr_ref.val, 500);
|
||||
JSValue v999 = JS_GetPropertyUint32(ctx, arr_ref.val, 999);
|
||||
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
|
||||
ASSERT_INT(v0, 0);
|
||||
ASSERT_INT(v500, 500);
|
||||
@@ -669,13 +681,16 @@ static JSValue cfunc_eq30(JSContext *ctx, JSValue this_val, int argc, JSValue *a
|
||||
}
|
||||
|
||||
TEST(array_slice_basic) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JSGCRef arr_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, i * 10)); /* [0, 10, 20, 30, 40] */
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, i * 10)); /* [0, 10, 20, 30, 40] */
|
||||
}
|
||||
|
||||
/* JS_Array(arr, from, to) = slice */
|
||||
JSValue sliced = JS_Array(ctx, arr, JS_NewInt32(ctx, 1), JS_NewInt32(ctx, 4), JS_NULL);
|
||||
JSValue sliced = JS_Array(ctx, arr_ref.val, JS_NewInt32(ctx, 1), JS_NewInt32(ctx, 4), JS_NULL);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsArray(sliced));
|
||||
|
||||
int64_t len;
|
||||
@@ -692,16 +707,21 @@ TEST(array_slice_basic) {
|
||||
}
|
||||
|
||||
TEST(array_concat_basic) {
|
||||
JSValue arr1 = JS_NewArray(ctx);
|
||||
JSValue arr2 = JS_NewArray(ctx);
|
||||
JSGCRef arr1_ref, arr2_ref;
|
||||
JS_PushGCRef(ctx, &arr1_ref);
|
||||
JS_PushGCRef(ctx, &arr2_ref);
|
||||
arr1_ref.val = JS_NewArray(ctx);
|
||||
arr2_ref.val = JS_NewArray(ctx);
|
||||
|
||||
JS_ArrayPush(ctx, &arr1, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr1, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr2, JS_NewInt32(ctx, 3));
|
||||
JS_ArrayPush(ctx, &arr2, JS_NewInt32(ctx, 4));
|
||||
JS_ArrayPush(ctx, &arr1_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr1_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr2_ref.val, JS_NewInt32(ctx, 3));
|
||||
JS_ArrayPush(ctx, &arr2_ref.val, JS_NewInt32(ctx, 4));
|
||||
|
||||
/* JS_Array(arr, arr2) = concat */
|
||||
JSValue result = JS_Array(ctx, arr1, arr2, JS_NULL, JS_NULL);
|
||||
JSValue result = JS_Array(ctx, arr1_ref.val, arr2_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &arr2_ref);
|
||||
JS_PopGCRef(ctx, &arr1_ref);
|
||||
ASSERT(JS_IsArray(result));
|
||||
|
||||
int64_t len;
|
||||
@@ -716,14 +736,17 @@ TEST(array_concat_basic) {
|
||||
}
|
||||
|
||||
TEST(array_sort_numbers) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 30));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 50));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 20));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 40));
|
||||
JSGCRef arr_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 30));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 50));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 20));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 40));
|
||||
|
||||
JSValue sorted = JS_ArraySort(ctx, arr, JS_NULL);
|
||||
JSValue sorted = JS_ArraySort(ctx, arr_ref.val, JS_NULL);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsArray(sorted));
|
||||
|
||||
int64_t len;
|
||||
@@ -739,46 +762,59 @@ TEST(array_sort_numbers) {
|
||||
}
|
||||
|
||||
TEST(array_find_value) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 20));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 30));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 40));
|
||||
JSGCRef arr_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 20));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 30));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 40));
|
||||
|
||||
/* Find by value: JS_ArrayFind(arr, target, reverse, from) */
|
||||
JSValue idx = JS_ArrayFind(ctx, arr, JS_NewInt32(ctx, 30), JS_NULL, JS_NULL);
|
||||
JSValue idx = JS_ArrayFind(ctx, arr_ref.val, JS_NewInt32(ctx, 30), JS_NULL, JS_NULL);
|
||||
ASSERT(JS_IsInt(idx));
|
||||
ASSERT(JS_VALUE_GET_INT(idx) == 2);
|
||||
|
||||
/* Not found returns null */
|
||||
JSValue not_found = JS_ArrayFind(ctx, arr, JS_NewInt32(ctx, 99), JS_NULL, JS_NULL);
|
||||
JSValue not_found = JS_ArrayFind(ctx, arr_ref.val, JS_NewInt32(ctx, 99), JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsNull(not_found));
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(array_find_predicate) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 20));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 30));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 40));
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 20));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 30));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 40));
|
||||
|
||||
/* Find by predicate function */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_eq30, "eq30", 1);
|
||||
JSValue idx = JS_ArrayFind(ctx, arr, func, JS_NULL, JS_NULL);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_eq30, "eq30", 1);
|
||||
JSValue idx = JS_ArrayFind(ctx, arr_ref.val, func_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT_INT(idx, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(array_filter_basic) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, i));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, i));
|
||||
}
|
||||
|
||||
/* Filter for values > 5 */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_gt5, "gt5", 1);
|
||||
JSValue filtered = JS_ArrayFilter(ctx, arr, func);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_gt5, "gt5", 1);
|
||||
JSValue filtered = JS_ArrayFilter(ctx, arr_ref.val, func_ref.val);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsArray(filtered));
|
||||
|
||||
int64_t len;
|
||||
@@ -791,14 +827,19 @@ TEST(array_filter_basic) {
|
||||
}
|
||||
|
||||
TEST(array_filter_even) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, i));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, i));
|
||||
}
|
||||
|
||||
/* Filter for even values */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_is_even, "is_even", 1);
|
||||
JSValue filtered = JS_ArrayFilter(ctx, arr, func);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_is_even, "is_even", 1);
|
||||
JSValue filtered = JS_ArrayFilter(ctx, arr_ref.val, func_ref.val);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsArray(filtered));
|
||||
|
||||
int64_t len;
|
||||
@@ -814,14 +855,19 @@ TEST(array_filter_even) {
|
||||
}
|
||||
|
||||
TEST(array_map_double) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 3));
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 3));
|
||||
|
||||
/* JS_Array(arr, fn, reverse, exit) = map */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_double, "double", 1);
|
||||
JSValue mapped = JS_Array(ctx, arr, func, JS_NULL, JS_NULL);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_double, "double", 1);
|
||||
JSValue mapped = JS_Array(ctx, arr_ref.val, func_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsArray(mapped));
|
||||
|
||||
int64_t len;
|
||||
@@ -835,42 +881,57 @@ TEST(array_map_double) {
|
||||
}
|
||||
|
||||
TEST(array_reduce_sum) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 3));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 4));
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 3));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 4));
|
||||
|
||||
/* Sum: 1 + 2 + 3 + 4 = 10 */
|
||||
/* JS_ArrayReduce(arr, fn, initial, reverse) */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_add, "add", 2);
|
||||
JSValue result = JS_ArrayReduce(ctx, arr, func, JS_NULL, JS_NULL);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_add, "add", 2);
|
||||
JSValue result = JS_ArrayReduce(ctx, arr_ref.val, func_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT_INT(result, 10);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(array_reduce_with_initial) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 3));
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 3));
|
||||
|
||||
/* Sum with initial 100: 100 + 1 + 2 + 3 = 106 */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_add, "add", 2);
|
||||
JSValue result = JS_ArrayReduce(ctx, arr, func, JS_NewInt32(ctx, 100), JS_NULL);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_add, "add", 2);
|
||||
JSValue result = JS_ArrayReduce(ctx, arr_ref.val, func_ref.val, JS_NewInt32(ctx, 100), JS_NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT_INT(result, 106);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(array_foreach_basic) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 3));
|
||||
JSGCRef arr_ref, func_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 3));
|
||||
|
||||
/* JS_ArrFor(arr, fn, reverse, exit) */
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_double, "double", 1);
|
||||
JSValue result = JS_ArrFor(ctx, arr, func, JS_NULL, JS_NULL);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_double, "double", 1);
|
||||
JSValue result = JS_ArrFor(ctx, arr_ref.val, func_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsNull(result));
|
||||
return 1;
|
||||
}
|
||||
@@ -1268,11 +1329,14 @@ TEST(cell_not) {
|
||||
============================================================================ */
|
||||
|
||||
TEST(cell_length_array) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 3));
|
||||
JSValue result = JS_CellLength(ctx, arr);
|
||||
JSGCRef arr_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 3));
|
||||
JSValue result = JS_CellLength(ctx, arr_ref.val);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT_INT(result, 3);
|
||||
return 1;
|
||||
}
|
||||
@@ -1285,11 +1349,14 @@ TEST(cell_length_string) {
|
||||
}
|
||||
|
||||
TEST(cell_reverse_array) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 3));
|
||||
JSValue reversed = JS_CellReverse(ctx, arr);
|
||||
JSGCRef arr_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 3));
|
||||
JSValue reversed = JS_CellReverse(ctx, arr_ref.val);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsArray(reversed));
|
||||
ASSERT_INT(JS_GetPropertyUint32(ctx, reversed, 0), 3);
|
||||
ASSERT_INT(JS_GetPropertyUint32(ctx, reversed, 1), 2);
|
||||
@@ -1308,9 +1375,13 @@ TEST(cell_reverse_string) {
|
||||
}
|
||||
|
||||
TEST(cell_meme_shallow) {
|
||||
JSValue obj = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, obj, "x", JS_NewInt32(ctx, 10));
|
||||
JSValue copy = JS_CellMeme(ctx, obj, JS_FALSE);
|
||||
JSGCRef obj_ref;
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
JSValue v10 = JS_NewInt32(ctx, 10);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, "x", v10);
|
||||
JSValue copy = JS_CellMeme(ctx, obj_ref.val, JS_FALSE);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
ASSERT(JS_IsRecord(copy));
|
||||
JSValue x = JS_GetPropertyStr(ctx, copy, "x");
|
||||
ASSERT_INT(x, 10);
|
||||
@@ -1357,9 +1428,13 @@ TEST(parse_json_nested) {
|
||||
}
|
||||
|
||||
TEST(stringify_json_object) {
|
||||
JSValue obj = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, obj, "a", JS_NewInt32(ctx, 1));
|
||||
JSValue str = JS_JSONStringify(ctx, obj, JS_NULL, JS_NULL);
|
||||
JSGCRef obj_ref;
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
JSValue v1 = JS_NewInt32(ctx, 1);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, "a", v1);
|
||||
JSValue str = JS_JSONStringify(ctx, obj_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
ASSERT(JS_IsText(str));
|
||||
const char *s = JS_ToCString(ctx, str);
|
||||
ASSERT(strstr(s, "\"a\"") != NULL);
|
||||
@@ -1369,10 +1444,13 @@ TEST(stringify_json_object) {
|
||||
}
|
||||
|
||||
TEST(stringify_json_array) {
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 2));
|
||||
JSValue str = JS_JSONStringify(ctx, arr, JS_NULL, JS_NULL);
|
||||
JSGCRef arr_ref;
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 1));
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 2));
|
||||
JSValue str = JS_JSONStringify(ctx, arr_ref.val, JS_NULL, JS_NULL);
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
ASSERT(JS_IsText(str));
|
||||
const char *s = JS_ToCString(ctx, str);
|
||||
ASSERT(strcmp(s, "[1,2]") == 0);
|
||||
@@ -1399,33 +1477,43 @@ static JSValue cfunc_sum_args(JSContext *ctx, JSValue this_val, int argc, JSValu
|
||||
}
|
||||
|
||||
TEST(new_cfunction_no_args) {
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_return_42, "return42", 0);
|
||||
ASSERT(JS_IsFunction(func));
|
||||
JSValue result = JS_Call(ctx, func, JS_NULL, 0, NULL);
|
||||
JSGCRef func_ref;
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_return_42, "return42", 0);
|
||||
ASSERT(JS_IsFunction(func_ref.val));
|
||||
JSValue result = JS_Call(ctx, func_ref.val, JS_NULL, 0, NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
ASSERT_INT(result, 42);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(new_cfunction_with_args) {
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_sum_args, "sum", 3);
|
||||
ASSERT(JS_IsFunction(func));
|
||||
JSGCRef func_ref;
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_sum_args, "sum", 3);
|
||||
ASSERT(JS_IsFunction(func_ref.val));
|
||||
/* JS_NewInt32 creates immediates, no GC risk */
|
||||
JSValue args[3] = {
|
||||
JS_NewInt32(ctx, 10),
|
||||
JS_NewInt32(ctx, 20),
|
||||
JS_NewInt32(ctx, 30)
|
||||
};
|
||||
JSValue result = JS_Call(ctx, func, JS_NULL, 3, args);
|
||||
JSValue result = JS_Call(ctx, func_ref.val, JS_NULL, 3, args);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
ASSERT_INT(result, 60);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(call_function_on_global) {
|
||||
JSGCRef func_ref;
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
JSValue global = JS_GetGlobalObject(ctx);
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_return_42, "testFunc", 0);
|
||||
JS_SetPropertyStr(ctx, global, "testFunc", func);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_return_42, "testFunc", 0);
|
||||
JS_SetPropertyStr(ctx, global, "testFunc", func_ref.val);
|
||||
JSValue got = JS_GetPropertyStr(ctx, global, "testFunc");
|
||||
ASSERT(JS_IsFunction(got));
|
||||
JSValue result = JS_Call(ctx, got, JS_NULL, 0, NULL);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
ASSERT_INT(result, 42);
|
||||
return 1;
|
||||
}
|
||||
@@ -1435,30 +1523,46 @@ TEST(call_function_on_global) {
|
||||
============================================================================ */
|
||||
|
||||
TEST(get_property_with_jsvalue_key) {
|
||||
JSValue obj = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, obj, "foo", JS_NewInt32(ctx, 123));
|
||||
JSGCRef obj_ref;
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
JSValue v123 = JS_NewInt32(ctx, 123);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, "foo", v123);
|
||||
JSValue key = JS_NewString(ctx, "foo");
|
||||
JSValue val = JS_GetProperty(ctx, obj, key);
|
||||
JSValue val = JS_GetProperty(ctx, obj_ref.val, key);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
ASSERT_INT(val, 123);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(set_property_with_jsvalue_key) {
|
||||
JSValue obj = JS_NewObject(ctx);
|
||||
JSValue key = JS_NewString(ctx, "bar");
|
||||
int r = JS_SetProperty(ctx, obj, key, JS_NewInt32(ctx, 456));
|
||||
JSGCRef obj_ref, key_ref;
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
JS_PushGCRef(ctx, &key_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
key_ref.val = JS_NewString(ctx, "bar");
|
||||
JSValue v456 = JS_NewInt32(ctx, 456);
|
||||
int r = JS_SetProperty(ctx, obj_ref.val, key_ref.val, v456);
|
||||
ASSERT(r >= 0);
|
||||
JSValue val = JS_GetPropertyStr(ctx, obj, "bar");
|
||||
JSValue val = JS_GetPropertyStr(ctx, obj_ref.val, "bar");
|
||||
JS_PopGCRef(ctx, &key_ref);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
ASSERT_INT(val, 456);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(get_own_property_names) {
|
||||
JSValue obj = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, obj, "a", JS_NewInt32(ctx, 1));
|
||||
JS_SetPropertyStr(ctx, obj, "b", JS_NewInt32(ctx, 2));
|
||||
JS_SetPropertyStr(ctx, obj, "c", JS_NewInt32(ctx, 3));
|
||||
JSValue names = JS_GetOwnPropertyNames(ctx, obj);
|
||||
JSGCRef obj_ref;
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
JSValue v1 = JS_NewInt32(ctx, 1);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, "a", v1);
|
||||
JSValue v2 = JS_NewInt32(ctx, 2);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, "b", v2);
|
||||
JSValue v3 = JS_NewInt32(ctx, 3);
|
||||
JS_SetPropertyStr(ctx, obj_ref.val, "c", v3);
|
||||
JSValue names = JS_GetOwnPropertyNames(ctx, obj_ref.val);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
ASSERT(JS_IsArray(names));
|
||||
int64_t len;
|
||||
JS_GetLength(ctx, names, &len);
|
||||
@@ -1467,30 +1571,37 @@ TEST(get_own_property_names) {
|
||||
}
|
||||
|
||||
TEST(property_type_restrictions) {
|
||||
JSValue obj = JS_NewObject(ctx);
|
||||
JSValue arr = JS_NewArray(ctx);
|
||||
JSGCRef obj_ref, arr_ref;
|
||||
JS_PushGCRef(ctx, &obj_ref);
|
||||
JS_PushGCRef(ctx, &arr_ref);
|
||||
obj_ref.val = JS_NewObject(ctx);
|
||||
arr_ref.val = JS_NewArray(ctx);
|
||||
|
||||
/* Setting numeric properties on non-arrays should throw */
|
||||
int ret = JS_SetPropertyUint32(ctx, obj, 0, JS_NewInt32(ctx, 100));
|
||||
JSValue v100 = JS_NewInt32(ctx, 100);
|
||||
int ret = JS_SetPropertyUint32(ctx, obj_ref.val, 0, v100);
|
||||
ASSERT(ret < 0); /* Should fail */
|
||||
ASSERT(JS_HasException(ctx)); /* Exception should be set */
|
||||
JS_GetException(ctx); /* Clear the exception */
|
||||
|
||||
/* Getting numeric properties on objects should return null */
|
||||
JSValue v0 = JS_GetPropertyUint32(ctx, obj, 0);
|
||||
JSValue v0 = JS_GetPropertyUint32(ctx, obj_ref.val, 0);
|
||||
ASSERT(JS_IsNull(v0));
|
||||
|
||||
/* Getting text keys from arrays should return null */
|
||||
JS_ArrayPush(ctx, &arr, JS_NewInt32(ctx, 42)); /* arr[0] = 42 */
|
||||
JSValue v1 = JS_GetPropertyStr(ctx, arr, "foo");
|
||||
JS_ArrayPush(ctx, &arr_ref.val, JS_NewInt32(ctx, 42)); /* arr[0] = 42 */
|
||||
JSValue v1 = JS_GetPropertyStr(ctx, arr_ref.val, "foo");
|
||||
ASSERT(JS_IsNull(v1));
|
||||
|
||||
/* Setting text keys on arrays should throw */
|
||||
ret = JS_SetPropertyStr(ctx, arr, "bar", JS_NewInt32(ctx, 99));
|
||||
JSValue v99 = JS_NewInt32(ctx, 99);
|
||||
ret = JS_SetPropertyStr(ctx, arr_ref.val, "bar", v99);
|
||||
ASSERT(ret < 0); /* Should fail */
|
||||
ASSERT(JS_HasException(ctx)); /* Exception should be set */
|
||||
JS_GetException(ctx); /* Clear the exception */
|
||||
|
||||
JS_PopGCRef(ctx, &arr_ref);
|
||||
JS_PopGCRef(ctx, &obj_ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1499,9 +1610,13 @@ TEST(property_type_restrictions) {
|
||||
============================================================================ */
|
||||
|
||||
TEST(get_prototype) {
|
||||
JSValue proto = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, proto, "inherited", JS_NewInt32(ctx, 999));
|
||||
JSValue obj = JS_NewObjectProto(ctx, proto);
|
||||
JSGCRef proto_ref;
|
||||
JS_PushGCRef(ctx, &proto_ref);
|
||||
proto_ref.val = JS_NewObject(ctx);
|
||||
JSValue v999 = JS_NewInt32(ctx, 999);
|
||||
JS_SetPropertyStr(ctx, proto_ref.val, "inherited", v999);
|
||||
JSValue obj = JS_NewObjectProto(ctx, proto_ref.val);
|
||||
JS_PopGCRef(ctx, &proto_ref);
|
||||
JSValue gotProto = JS_GetPrototype(ctx, obj);
|
||||
ASSERT(JS_IsRecord(gotProto));
|
||||
JSValue inherited = JS_GetPropertyStr(ctx, gotProto, "inherited");
|
||||
@@ -1510,9 +1625,13 @@ TEST(get_prototype) {
|
||||
}
|
||||
|
||||
TEST(cell_proto) {
|
||||
JSValue proto = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, proto, "value", JS_NewInt32(ctx, 42));
|
||||
JSValue obj = JS_NewObjectProto(ctx, proto);
|
||||
JSGCRef proto_ref;
|
||||
JS_PushGCRef(ctx, &proto_ref);
|
||||
proto_ref.val = JS_NewObject(ctx);
|
||||
JSValue v42 = JS_NewInt32(ctx, 42);
|
||||
JS_SetPropertyStr(ctx, proto_ref.val, "value", v42);
|
||||
JSValue obj = JS_NewObjectProto(ctx, proto_ref.val);
|
||||
JS_PopGCRef(ctx, &proto_ref);
|
||||
JSValue gotProto = JS_CellProto(ctx, obj);
|
||||
ASSERT(JS_IsRecord(gotProto));
|
||||
JSValue val = JS_GetPropertyStr(ctx, gotProto, "value");
|
||||
@@ -1555,23 +1674,35 @@ TEST(new_array_len) {
|
||||
============================================================================ */
|
||||
|
||||
TEST(cell_apply) {
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_sum_args, "sum", 3);
|
||||
JSValue args = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &args, JS_NewInt32(ctx, 5));
|
||||
JS_ArrayPush(ctx, &args, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &args, JS_NewInt32(ctx, 15));
|
||||
JSValue result = JS_CellApply(ctx, func, args);
|
||||
JSGCRef func_ref, args_ref;
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
JS_PushGCRef(ctx, &args_ref);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_sum_args, "sum", 3);
|
||||
args_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &args_ref.val, JS_NewInt32(ctx, 5));
|
||||
JS_ArrayPush(ctx, &args_ref.val, JS_NewInt32(ctx, 10));
|
||||
JS_ArrayPush(ctx, &args_ref.val, JS_NewInt32(ctx, 15));
|
||||
JSValue result = JS_CellApply(ctx, func_ref.val, args_ref.val);
|
||||
JS_PopGCRef(ctx, &args_ref);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
ASSERT_INT(result, 30);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST(cell_call) {
|
||||
JSValue func = JS_NewCFunction(ctx, cfunc_sum_args, "sum", 2);
|
||||
JSValue this_obj = JS_NewObject(ctx);
|
||||
JSValue args = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &args, JS_NewInt32(ctx, 7));
|
||||
JS_ArrayPush(ctx, &args, JS_NewInt32(ctx, 8));
|
||||
JSValue result = JS_CellCall(ctx, func, this_obj, args);
|
||||
JSGCRef func_ref, this_ref, args_ref;
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
JS_PushGCRef(ctx, &this_ref);
|
||||
JS_PushGCRef(ctx, &args_ref);
|
||||
func_ref.val = JS_NewCFunction(ctx, cfunc_sum_args, "sum", 2);
|
||||
this_ref.val = JS_NewObject(ctx);
|
||||
args_ref.val = JS_NewArray(ctx);
|
||||
JS_ArrayPush(ctx, &args_ref.val, JS_NewInt32(ctx, 7));
|
||||
JS_ArrayPush(ctx, &args_ref.val, JS_NewInt32(ctx, 8));
|
||||
JSValue result = JS_CellCall(ctx, func_ref.val, this_ref.val, args_ref.val);
|
||||
JS_PopGCRef(ctx, &args_ref);
|
||||
JS_PopGCRef(ctx, &this_ref);
|
||||
JS_PopGCRef(ctx, &func_ref);
|
||||
ASSERT_INT(result, 15);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user