JavaScript-QuickJS

 view release on metacpan or  search on metacpan

easyxs/ppport.h  view on Meta::CPAN

PL_body_arenas|5.009004||Viu
PL_body_roots|5.009003||Viu
PL_bodytarget|5.005000||Viu
PL_breakable_sub_gen|5.010001||Viu
PL_bufend||5.003007|ponu
PL_bufptr||5.003007|ponu
PL_CCC_non0_non230|5.029008||Viu
PL_check|5.009003|5.006000|
PL_checkav|5.006000||Viu
PL_checkav_save|5.008001||Viu
PL_chopset|5.005000||Viu
PL_clocktick|5.008001||Viu
PL_collation_ix|5.005000||Viu
PL_collation_name|5.005000||Viu
PL_collation_standard|5.005000||Viu
PL_collxfrm_base|5.005000||Viu
PL_collxfrm_mult|5.005000||Viu
PL_colors|5.005000||Viu
PL_colorset|5.005000||Viu
PL_compcv|5.005000||Viu
PL_compiling|5.005000|5.003007|poVnu

quickjs/quickjs.c  view on Meta::CPAN

/* return -1 if exception, 0 if no operator overloading, 1 if
   overloaded operator called */
static __exception int js_call_binary_op_fallback(JSContext *ctx,
                                                  JSValue *pret,
                                                  JSValueConst op1,
                                                  JSValueConst op2,
                                                  OPCodeEnum op,
                                                  BOOL is_numeric,
                                                  int hint)
{
    JSValue opset1_obj, opset2_obj, method, ret, new_op1, new_op2;
    JSOperatorSetData *opset1, *opset2;
    JSOverloadableOperatorEnum ovop;
    JSObject *p;
    JSValueConst args[2];
    
    if (!ctx->allow_operator_overloading)
        return 0;
    
    opset2_obj = JS_UNDEFINED;
    opset1_obj = JS_GetProperty(ctx, op1, JS_ATOM_Symbol_operatorSet);
    if (JS_IsException(opset1_obj))
        goto exception;
    if (JS_IsUndefined(opset1_obj))
        return 0;
    opset1 = JS_GetOpaque2(ctx, opset1_obj, JS_CLASS_OPERATOR_SET);
    if (!opset1)
        goto exception;

    opset2_obj = JS_GetProperty(ctx, op2, JS_ATOM_Symbol_operatorSet);
    if (JS_IsException(opset2_obj))
        goto exception;
    if (JS_IsUndefined(opset2_obj)) {
        JS_FreeValue(ctx, opset1_obj);
        return 0;
    }
    opset2 = JS_GetOpaque2(ctx, opset2_obj, JS_CLASS_OPERATOR_SET);
    if (!opset2)
        goto exception;

    if (opset1->is_primitive && opset2->is_primitive) {
        JS_FreeValue(ctx, opset1_obj);
        JS_FreeValue(ctx, opset2_obj);
        return 0;
    }

    ovop = get_ovop_from_opcode(op);
    
    if (opset1->operator_counter == opset2->operator_counter) {
        p = opset1->self_ops[ovop];
    } else if (opset1->operator_counter > opset2->operator_counter) {
        p = find_binary_op(&opset1->left, opset2->operator_counter, ovop);
    } else {
        p = find_binary_op(&opset2->right, opset1->operator_counter, ovop);
    }
    if (!p) {
        JS_ThrowTypeError(ctx, "operator %s: no function defined",
                          js_overloadable_operator_names[ovop]);
        goto exception;
    }

    if (opset1->is_primitive) {
        if (is_numeric) {
            new_op1 = JS_ToNumeric(ctx, op1);
        } else {
            new_op1 = JS_ToPrimitive(ctx, op1, hint);
        }
        if (JS_IsException(new_op1))
            goto exception;
    } else {
        new_op1 = JS_DupValue(ctx, op1);
    }
    
    if (opset2->is_primitive) {
        if (is_numeric) {
            new_op2 = JS_ToNumeric(ctx, op2);
        } else {
            new_op2 = JS_ToPrimitive(ctx, op2, hint);
        }
        if (JS_IsException(new_op2)) {
            JS_FreeValue(ctx, new_op1);
            goto exception;
        }
    } else {

quickjs/quickjs.c  view on Meta::CPAN

    } else if (ovop == JS_OVOP_LESS) {
        if (JS_IsUndefined(ret)) {
            ret = JS_FALSE;
        } else {
            BOOL res = JS_ToBoolFree(ctx, ret);
            if (op == OP_lte || op == OP_gte)
                res ^= 1;
            ret = JS_NewBool(ctx, res);
        }
    }
    JS_FreeValue(ctx, opset1_obj);
    JS_FreeValue(ctx, opset2_obj);
    *pret = ret;
    return 1;
 exception:
    JS_FreeValue(ctx, opset1_obj);
    JS_FreeValue(ctx, opset2_obj);
    *pret = JS_UNDEFINED;
    return -1;
}

/* try to call the operation on the operatorSet field of 'obj'. Only
   used for "/" and "**" on the BigInt prototype in math mode */
static __exception int js_call_binary_op_simple(JSContext *ctx,
                                                JSValue *pret,
                                                JSValueConst obj,
                                                JSValueConst op1,
                                                JSValueConst op2,
                                                OPCodeEnum op)
{
    JSValue opset1_obj, method, ret, new_op1, new_op2;
    JSOperatorSetData *opset1;
    JSOverloadableOperatorEnum ovop;
    JSObject *p;
    JSValueConst args[2];

    opset1_obj = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_operatorSet);
    if (JS_IsException(opset1_obj))
        goto exception;
    if (JS_IsUndefined(opset1_obj))
        return 0;
    opset1 = JS_GetOpaque2(ctx, opset1_obj, JS_CLASS_OPERATOR_SET);
    if (!opset1)
        goto exception;
    ovop = get_ovop_from_opcode(op);

    p = opset1->self_ops[ovop];
    if (!p) {
        JS_FreeValue(ctx, opset1_obj);
        return 0;
    }

    new_op1 = JS_ToNumeric(ctx, op1);
    if (JS_IsException(new_op1))
        goto exception;
    new_op2 = JS_ToNumeric(ctx, op2);
    if (JS_IsException(new_op2)) {
        JS_FreeValue(ctx, new_op1);
        goto exception;
    }

    method = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
    args[0] = new_op1;
    args[1] = new_op2;
    ret = JS_CallFree(ctx, method, JS_UNDEFINED, 2, args);
    JS_FreeValue(ctx, new_op1);
    JS_FreeValue(ctx, new_op2);
    if (JS_IsException(ret))
        goto exception;
    JS_FreeValue(ctx, opset1_obj);
    *pret = ret;
    return 1;
 exception:
    JS_FreeValue(ctx, opset1_obj);
    *pret = JS_UNDEFINED;
    return -1;
}

/* return -1 if exception, 0 if no operator overloading, 1 if
   overloaded operator called */
static __exception int js_call_unary_op_fallback(JSContext *ctx,
                                                 JSValue *pret,
                                                 JSValueConst op1,
                                                 OPCodeEnum op)
{
    JSValue opset1_obj, method, ret;
    JSOperatorSetData *opset1;
    JSOverloadableOperatorEnum ovop;
    JSObject *p;

    if (!ctx->allow_operator_overloading)
        return 0;
    
    opset1_obj = JS_GetProperty(ctx, op1, JS_ATOM_Symbol_operatorSet);
    if (JS_IsException(opset1_obj))
        goto exception;
    if (JS_IsUndefined(opset1_obj))
        return 0;
    opset1 = JS_GetOpaque2(ctx, opset1_obj, JS_CLASS_OPERATOR_SET);
    if (!opset1)
        goto exception;
    if (opset1->is_primitive) {
        JS_FreeValue(ctx, opset1_obj);
        return 0;
    }

    ovop = get_ovop_from_opcode(op);

    p = opset1->self_ops[ovop];
    if (!p) {
        JS_ThrowTypeError(ctx, "no overloaded operator %s",
                          js_overloadable_operator_names[ovop]);
        goto exception;
    }
    method = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
    ret = JS_CallFree(ctx, method, JS_UNDEFINED, 1, &op1);
    if (JS_IsException(ret))
        goto exception;
    JS_FreeValue(ctx, opset1_obj);
    *pret = ret;
    return 1;
 exception:
    JS_FreeValue(ctx, opset1_obj);
    *pret = JS_UNDEFINED;
    return -1;
}

static int js_unary_arith_bigfloat(JSContext *ctx,
                                   JSValue *pres, OPCodeEnum op, JSValue op1)
{
    bf_t a_s, *r, *a;
    int ret, v;
    JSValue res;

quickjs/quickjs.c  view on Meta::CPAN

{
    ctx->eval_internal = __JS_EvalInternal;
}

#ifdef CONFIG_BIGNUM

/* Operators */

static void js_operator_set_finalizer(JSRuntime *rt, JSValue val)
{
    JSOperatorSetData *opset = JS_GetOpaque(val, JS_CLASS_OPERATOR_SET);
    int i, j;
    JSBinaryOperatorDefEntry *ent;
    
    if (opset) {
        for(i = 0; i < JS_OVOP_COUNT; i++) {
            if (opset->self_ops[i])
                JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, opset->self_ops[i]));
        }
        for(j = 0; j < opset->left.count; j++) {
            ent = &opset->left.tab[j];
            for(i = 0; i < JS_OVOP_BINARY_COUNT; i++) {
                if (ent->ops[i])
                    JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i]));
            }
        }
        js_free_rt(rt, opset->left.tab);
        for(j = 0; j < opset->right.count; j++) {
            ent = &opset->right.tab[j];
            for(i = 0; i < JS_OVOP_BINARY_COUNT; i++) {
                if (ent->ops[i])
                    JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i]));
            }
        }
        js_free_rt(rt, opset->right.tab);
        js_free_rt(rt, opset);
    }
}

static void js_operator_set_mark(JSRuntime *rt, JSValueConst val,
                                 JS_MarkFunc *mark_func)
{
    JSOperatorSetData *opset = JS_GetOpaque(val, JS_CLASS_OPERATOR_SET);
    int i, j;
    JSBinaryOperatorDefEntry *ent;
    
    if (opset) {
        for(i = 0; i < JS_OVOP_COUNT; i++) {
            if (opset->self_ops[i])
                JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, opset->self_ops[i]),
                             mark_func);
        }
        for(j = 0; j < opset->left.count; j++) {
            ent = &opset->left.tab[j];
            for(i = 0; i < JS_OVOP_BINARY_COUNT; i++) {
                if (ent->ops[i])
                    JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i]),
                                 mark_func);
            }
        }
        for(j = 0; j < opset->right.count; j++) {
            ent = &opset->right.tab[j];
            for(i = 0; i < JS_OVOP_BINARY_COUNT; i++) {
                if (ent->ops[i])
                    JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, ent->ops[i]),
                                 mark_func);
            }
        }
    }
}


/* create an OperatorSet object */
static JSValue js_operators_create_internal(JSContext *ctx,
                                            int argc, JSValueConst *argv,
                                            BOOL is_primitive)
{
    JSValue opset_obj, prop, obj;
    JSOperatorSetData *opset, *opset1;
    JSBinaryOperatorDef *def;
    JSValueConst arg;
    int i, j;
    JSBinaryOperatorDefEntry *new_tab;
    JSBinaryOperatorDefEntry *ent;
    uint32_t op_count;

    if (ctx->rt->operator_count == UINT32_MAX) {
        return JS_ThrowTypeError(ctx, "too many operators");
    }
    opset_obj = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_OPERATOR_SET);
    if (JS_IsException(opset_obj))
        goto fail;
    opset = js_mallocz(ctx, sizeof(*opset));
    if (!opset)
        goto fail;
    JS_SetOpaque(opset_obj, opset);
    if (argc >= 1) {
        arg = argv[0];
        /* self operators */
        for(i = 0; i < JS_OVOP_COUNT; i++) {
            prop = JS_GetPropertyStr(ctx, arg, js_overloadable_operator_names[i]);
            if (JS_IsException(prop))
                goto fail;
            if (!JS_IsUndefined(prop)) {
                if (check_function(ctx, prop)) {
                    JS_FreeValue(ctx, prop);
                    goto fail;
                }
                opset->self_ops[i] = JS_VALUE_GET_OBJ(prop);
            }
        }
    }
    /* left & right operators */
    for(j = 1; j < argc; j++) {
        arg = argv[j];
        prop = JS_GetPropertyStr(ctx, arg, "left");
        if (JS_IsException(prop))
            goto fail;
        def = &opset->right;
        if (JS_IsUndefined(prop)) {
            prop = JS_GetPropertyStr(ctx, arg, "right");
            if (JS_IsException(prop))
                goto fail;
            if (JS_IsUndefined(prop)) {
                JS_ThrowTypeError(ctx, "left or right property must be present");
                goto fail;
            }
            def = &opset->left;
        }
        /* get the operator set */
        obj = JS_GetProperty(ctx, prop, JS_ATOM_prototype);
        JS_FreeValue(ctx, prop);
        if (JS_IsException(obj))
            goto fail;
        prop = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_operatorSet);
        JS_FreeValue(ctx, obj);
        if (JS_IsException(prop))
            goto fail;
        opset1 = JS_GetOpaque2(ctx, prop, JS_CLASS_OPERATOR_SET);
        if (!opset1) {
            JS_FreeValue(ctx, prop);
            goto fail;
        }
        op_count = opset1->operator_counter;
        JS_FreeValue(ctx, prop);
        
        /* we assume there are few entries */
        new_tab = js_realloc(ctx, def->tab,
                             (def->count + 1) * sizeof(def->tab[0]));
        if (!new_tab)
            goto fail;
        def->tab = new_tab;
        def->count++;
        ent = def->tab + def->count - 1;

quickjs/quickjs.c  view on Meta::CPAN

                goto fail;
            if (!JS_IsUndefined(prop)) {
                if (check_function(ctx, prop)) {
                    JS_FreeValue(ctx, prop);
                    goto fail;
                }
                ent->ops[i] = JS_VALUE_GET_OBJ(prop);
            }
        }
    }
    opset->is_primitive = is_primitive;
    opset->operator_counter = ctx->rt->operator_count++;
    return opset_obj;
 fail:
    JS_FreeValue(ctx, opset_obj);
    return JS_EXCEPTION;
}

static JSValue js_operators_create(JSContext *ctx, JSValueConst this_val,
                                int argc, JSValueConst *argv)
{
    return js_operators_create_internal(ctx, argc, argv, FALSE);
}

static JSValue js_operators_updateBigIntOperators(JSContext *ctx, JSValueConst this_val,
                                                  int argc, JSValueConst *argv)
{
    JSValue opset_obj, prop;
    JSOperatorSetData *opset;
    const JSOverloadableOperatorEnum ops[2] = { JS_OVOP_DIV, JS_OVOP_POW };
    JSOverloadableOperatorEnum op;
    int i;
    
    opset_obj = JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_BIG_INT],
                               JS_ATOM_Symbol_operatorSet);
    if (JS_IsException(opset_obj))
        goto fail;
    opset = JS_GetOpaque2(ctx, opset_obj, JS_CLASS_OPERATOR_SET);
    if (!opset)
        goto fail;
    for(i = 0; i < countof(ops); i++) {
        op = ops[i];
        prop = JS_GetPropertyStr(ctx, argv[0],
                                 js_overloadable_operator_names[op]);
        if (JS_IsException(prop))
            goto fail;
        if (!JS_IsUndefined(prop)) {
            if (!JS_IsNull(prop) && check_function(ctx, prop)) {
                JS_FreeValue(ctx, prop);
                goto fail;
            }
            if (opset->self_ops[op])
                JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, opset->self_ops[op]));
            if (JS_IsNull(prop)) {
                opset->self_ops[op] = NULL;
            } else {
                opset->self_ops[op] = JS_VALUE_GET_PTR(prop);
            }
        }
    }
    JS_FreeValue(ctx, opset_obj);
    return JS_UNDEFINED;
 fail:
    JS_FreeValue(ctx, opset_obj);
    return JS_EXCEPTION;
}

static int js_operators_set_default(JSContext *ctx, JSValueConst obj)
{
    JSValue opset_obj;

    if (!JS_IsObject(obj)) /* in case the prototype is not defined */
        return 0;
    opset_obj = js_operators_create_internal(ctx, 0, NULL, TRUE);
    if (JS_IsException(opset_obj))
        return -1;
    /* cannot be modified by the user */
    JS_DefinePropertyValue(ctx, obj, JS_ATOM_Symbol_operatorSet,
                           opset_obj, 0);
    return 0;
}

static JSValue js_dummy_operators_ctor(JSContext *ctx, JSValueConst new_target,
                                       int argc, JSValueConst *argv)
{
    return js_create_from_ctor(ctx, new_target, JS_CLASS_OBJECT);
}

static JSValue js_global_operators(JSContext *ctx, JSValueConst this_val,
                                   int argc, JSValueConst *argv)
{
    JSValue func_obj, proto, opset_obj;

    func_obj = JS_UNDEFINED;
    proto = JS_NewObject(ctx);
    if (JS_IsException(proto))
        return JS_EXCEPTION;
    opset_obj = js_operators_create_internal(ctx, argc, argv, FALSE);
    if (JS_IsException(opset_obj))
        goto fail;
    JS_DefinePropertyValue(ctx, proto, JS_ATOM_Symbol_operatorSet,
                           opset_obj, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
    func_obj = JS_NewCFunction2(ctx, js_dummy_operators_ctor, "Operators",
                                0, JS_CFUNC_constructor, 0);
    if (JS_IsException(func_obj))
        goto fail;
    JS_SetConstructor2(ctx, func_obj, proto,
                       0, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
    JS_FreeValue(ctx, proto);
    return func_obj;
 fail:
    JS_FreeValue(ctx, proto);



( run in 0.446 second using v1.01-cache-2.11-cpan-71847e10f99 )