mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	added Object.groupBy and Map.groupBy (initial patch by bnoordhuis)
This commit is contained in:
		
							parent
							
								
									4876f72a1a
								
							
						
					
					
						commit
						c2c773e135
					
				
							
								
								
									
										4
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								TODO
									
									
									
									
									
								
							@ -63,5 +63,5 @@ Optimization ideas:
 | 
			
		||||
Test262o:   0/11262 errors, 463 excluded
 | 
			
		||||
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
 | 
			
		||||
 | 
			
		||||
Result: 16/76419 errors, 1497 excluded, 8381 skipped
 | 
			
		||||
Test262 commit: 31126581e7290f9233c29cefd93f66c6ac78f1c9
 | 
			
		||||
Result: 16/76471 errors, 1497 excluded, 8355 skipped
 | 
			
		||||
Test262 commit: 6cbb6da9473c56d95358d8e679c5a6d2b4574efb
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										121
									
								
								quickjs.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								quickjs.c
									
									
									
									
									
								
							@ -1271,6 +1271,8 @@ static JSValue js_module_ns_autoinit(JSContext *ctx, JSObject *p, JSAtom atom,
 | 
			
		||||
static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p,
 | 
			
		||||
                                               JSAtom atom, void *opaque);
 | 
			
		||||
void JS_SetUncatchableError(JSContext *ctx, JSValueConst val, BOOL flag);
 | 
			
		||||
static JSValue js_object_groupBy(JSContext *ctx, JSValueConst this_val,
 | 
			
		||||
                                 int argc, JSValueConst *argv, int is_map);
 | 
			
		||||
 | 
			
		||||
static const JSClassExoticMethods js_arguments_exotic_methods;
 | 
			
		||||
static const JSClassExoticMethods js_string_exotic_methods;
 | 
			
		||||
@ -37711,6 +37713,7 @@ static const JSCFunctionListEntry js_object_funcs[] = {
 | 
			
		||||
    JS_CFUNC_DEF("defineProperties", 2, js_object_defineProperties ),
 | 
			
		||||
    JS_CFUNC_DEF("getOwnPropertyNames", 1, js_object_getOwnPropertyNames ),
 | 
			
		||||
    JS_CFUNC_DEF("getOwnPropertySymbols", 1, js_object_getOwnPropertySymbols ),
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 0 ),
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("keys", 1, js_object_keys, JS_ITERATOR_KIND_KEY ),
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("values", 1, js_object_keys, JS_ITERATOR_KIND_VALUE ),
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("entries", 1, js_object_keys, JS_ITERATOR_KIND_KEY_AND_VALUE ),
 | 
			
		||||
@ -46456,6 +46459,123 @@ static JSValue js_map_forEach(JSContext *ctx, JSValueConst this_val,
 | 
			
		||||
    return JS_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue js_object_groupBy(JSContext *ctx, JSValueConst this_val,
 | 
			
		||||
                                 int argc, JSValueConst *argv, int is_map)
 | 
			
		||||
{
 | 
			
		||||
    JSValueConst cb, args[2];
 | 
			
		||||
    JSValue res, iter, next, groups, key, v, prop;
 | 
			
		||||
    JSAtom key_atom = JS_ATOM_NULL;
 | 
			
		||||
    int64_t idx;
 | 
			
		||||
    BOOL done;
 | 
			
		||||
 | 
			
		||||
    // "is function?" check must be observed before argv[0] is accessed
 | 
			
		||||
    cb = argv[1];
 | 
			
		||||
    if (check_function(ctx, cb))
 | 
			
		||||
        return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
    iter = JS_GetIterator(ctx, argv[0], /*is_async*/FALSE);
 | 
			
		||||
    if (JS_IsException(iter))
 | 
			
		||||
        return JS_EXCEPTION;
 | 
			
		||||
 | 
			
		||||
    key = JS_UNDEFINED;
 | 
			
		||||
    key_atom = JS_ATOM_NULL;
 | 
			
		||||
    v = JS_UNDEFINED;
 | 
			
		||||
    prop = JS_UNDEFINED;
 | 
			
		||||
    groups = JS_UNDEFINED;
 | 
			
		||||
    
 | 
			
		||||
    next = JS_GetProperty(ctx, iter, JS_ATOM_next);
 | 
			
		||||
    if (JS_IsException(next))
 | 
			
		||||
        goto exception;
 | 
			
		||||
 | 
			
		||||
    if (is_map) {
 | 
			
		||||
        groups = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, 0);
 | 
			
		||||
    } else {
 | 
			
		||||
        groups = JS_NewObjectProto(ctx, JS_NULL);
 | 
			
		||||
    }
 | 
			
		||||
    if (JS_IsException(groups))
 | 
			
		||||
        goto exception;
 | 
			
		||||
 | 
			
		||||
    for (idx = 0; ; idx++) {
 | 
			
		||||
        if (idx >= MAX_SAFE_INTEGER) {
 | 
			
		||||
            JS_ThrowTypeError(ctx, "too many elements");
 | 
			
		||||
            goto iterator_close_exception;
 | 
			
		||||
        }
 | 
			
		||||
        v = JS_IteratorNext(ctx, iter, next, 0, NULL, &done);
 | 
			
		||||
        if (JS_IsException(v))
 | 
			
		||||
            goto exception;
 | 
			
		||||
        if (done)
 | 
			
		||||
            break; // v is JS_UNDEFINED
 | 
			
		||||
 | 
			
		||||
        args[0] = v;
 | 
			
		||||
        args[1] = JS_NewInt64(ctx, idx);
 | 
			
		||||
        key = JS_Call(ctx, cb, ctx->global_obj, 2, args);
 | 
			
		||||
        if (JS_IsException(key))
 | 
			
		||||
            goto iterator_close_exception;
 | 
			
		||||
 | 
			
		||||
        if (is_map) {
 | 
			
		||||
            prop = js_map_get(ctx, groups, 1, (JSValueConst *)&key, 0);
 | 
			
		||||
        } else {
 | 
			
		||||
            key_atom = JS_ValueToAtom(ctx, key);
 | 
			
		||||
            JS_FreeValue(ctx, key);
 | 
			
		||||
            key = JS_UNDEFINED;
 | 
			
		||||
            if (key_atom == JS_ATOM_NULL)
 | 
			
		||||
                goto iterator_close_exception;
 | 
			
		||||
            prop = JS_GetProperty(ctx, groups, key_atom);
 | 
			
		||||
        }
 | 
			
		||||
        if (JS_IsException(prop))
 | 
			
		||||
            goto exception;
 | 
			
		||||
 | 
			
		||||
        if (JS_IsUndefined(prop)) {
 | 
			
		||||
            prop = JS_NewArray(ctx);
 | 
			
		||||
            if (JS_IsException(prop))
 | 
			
		||||
                goto exception;
 | 
			
		||||
            if (is_map) {
 | 
			
		||||
                args[0] = key;
 | 
			
		||||
                args[1] = prop;
 | 
			
		||||
                res = js_map_set(ctx, groups, 2, args, 0);
 | 
			
		||||
                if (JS_IsException(res))
 | 
			
		||||
                    goto exception;
 | 
			
		||||
                JS_FreeValue(ctx, res);
 | 
			
		||||
            } else {
 | 
			
		||||
                prop = JS_DupValue(ctx, prop);
 | 
			
		||||
                if (JS_DefinePropertyValue(ctx, groups, key_atom, prop,
 | 
			
		||||
                                           JS_PROP_C_W_E) < 0) {
 | 
			
		||||
                    goto exception;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        res = js_array_push(ctx, prop, 1, (JSValueConst *)&v, /*unshift*/0);
 | 
			
		||||
        if (JS_IsException(res))
 | 
			
		||||
            goto exception;
 | 
			
		||||
        // res is an int64
 | 
			
		||||
 | 
			
		||||
        JS_FreeValue(ctx, prop);
 | 
			
		||||
        JS_FreeValue(ctx, key);
 | 
			
		||||
        JS_FreeAtom(ctx, key_atom);
 | 
			
		||||
        JS_FreeValue(ctx, v);
 | 
			
		||||
        prop = JS_UNDEFINED;
 | 
			
		||||
        key = JS_UNDEFINED;
 | 
			
		||||
        key_atom = JS_ATOM_NULL;
 | 
			
		||||
        v = JS_UNDEFINED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    JS_FreeValue(ctx, iter);
 | 
			
		||||
    JS_FreeValue(ctx, next);
 | 
			
		||||
    return groups;
 | 
			
		||||
 | 
			
		||||
 iterator_close_exception:
 | 
			
		||||
    JS_IteratorClose(ctx, iter, TRUE);
 | 
			
		||||
 exception:
 | 
			
		||||
    JS_FreeAtom(ctx, key_atom);
 | 
			
		||||
    JS_FreeValue(ctx, prop);
 | 
			
		||||
    JS_FreeValue(ctx, key);
 | 
			
		||||
    JS_FreeValue(ctx, v);
 | 
			
		||||
    JS_FreeValue(ctx, groups);
 | 
			
		||||
    JS_FreeValue(ctx, iter);
 | 
			
		||||
    JS_FreeValue(ctx, next);
 | 
			
		||||
    return JS_EXCEPTION;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void js_map_finalizer(JSRuntime *rt, JSValue val)
 | 
			
		||||
{
 | 
			
		||||
    JSObject *p;
 | 
			
		||||
@ -46636,6 +46756,7 @@ static JSValue js_map_iterator_next(JSContext *ctx, JSValueConst this_val,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const JSCFunctionListEntry js_map_funcs[] = {
 | 
			
		||||
    JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 1 ),
 | 
			
		||||
    JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ AggregateError
 | 
			
		||||
align-detached-buffer-semantics-with-web-reality
 | 
			
		||||
arbitrary-module-namespace-names=skip
 | 
			
		||||
array-find-from-last
 | 
			
		||||
array-grouping=skip
 | 
			
		||||
array-grouping
 | 
			
		||||
Array.fromAsync=skip
 | 
			
		||||
Array.prototype.at
 | 
			
		||||
Array.prototype.flat
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user