optimize frames; remove trampoline
This commit is contained in:
@@ -10514,15 +10514,46 @@ JSValue JS_CellCall (JSContext *ctx, JSValue fn, JSValue this_val, JSValue args)
|
||||
return js_cell_call (ctx, JS_NULL, argc, argv);
|
||||
}
|
||||
|
||||
static int js_cell_read_number_strict (JSValue val, double *out) {
|
||||
uint32_t tag = JS_VALUE_GET_TAG (val);
|
||||
if (tag == JS_TAG_INT) {
|
||||
*out = (double)JS_VALUE_GET_INT (val);
|
||||
return 0;
|
||||
}
|
||||
if (JS_TAG_IS_FLOAT64 (tag)) {
|
||||
*out = JS_VALUE_GET_FLOAT64 (val);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static JSValue js_cell_number_from_double (JSContext *ctx, double d) {
|
||||
if (d >= INT32_MIN && d <= INT32_MAX) {
|
||||
int32_t i = (int32_t)d;
|
||||
if ((double)i == d)
|
||||
return JS_NewInt32 (ctx, i);
|
||||
}
|
||||
return JS_NewFloat64 (ctx, d);
|
||||
}
|
||||
|
||||
/* C API: modulo(a, b) - modulo operation */
|
||||
JSValue JS_CellModulo (JSContext *ctx, JSValue a, JSValue b) {
|
||||
JSValue argv[2] = { a, b };
|
||||
return js_cell_modulo (ctx, JS_NULL, 2, argv);
|
||||
double dividend, divisor;
|
||||
if (js_cell_read_number_strict (a, ÷nd) < 0) return JS_NULL;
|
||||
if (js_cell_read_number_strict (b, &divisor) < 0) return JS_NULL;
|
||||
if (isnan (dividend) || isnan (divisor)) return JS_NULL;
|
||||
if (divisor == 0.0) return JS_NULL;
|
||||
if (dividend == 0.0) return JS_NewFloat64 (ctx, 0.0);
|
||||
return js_cell_number_from_double (ctx,
|
||||
dividend - (divisor * floor (dividend / divisor)));
|
||||
}
|
||||
|
||||
/* C API: neg(val) - negate number */
|
||||
JSValue JS_CellNeg (JSContext *ctx, JSValue val) {
|
||||
return js_cell_neg (ctx, JS_NULL, 1, &val);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (val, &d) < 0) return JS_NULL;
|
||||
if (isnan (d)) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, -d);
|
||||
}
|
||||
|
||||
/* C API: not(val) - logical not */
|
||||
@@ -10647,60 +10678,86 @@ JSValue JS_CellNumber (JSContext *ctx, JSValue val) {
|
||||
|
||||
/* C API: abs(num) - absolute value */
|
||||
JSValue JS_CellAbs (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_abs (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, fabs (d));
|
||||
}
|
||||
|
||||
/* C API: sign(num) - sign of number (-1, 0, 1) */
|
||||
JSValue JS_CellSign (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_sign (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
if (d < 0) return JS_NewInt32 (ctx, -1);
|
||||
if (d > 0) return JS_NewInt32 (ctx, 1);
|
||||
return JS_NewInt32 (ctx, 0);
|
||||
}
|
||||
|
||||
/* C API: floor(num) - floor */
|
||||
JSValue JS_CellFloor (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_floor (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, floor (d));
|
||||
}
|
||||
|
||||
/* C API: ceiling(num) - ceiling */
|
||||
JSValue JS_CellCeiling (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_ceiling (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, ceil (d));
|
||||
}
|
||||
|
||||
/* C API: round(num) - round to nearest integer */
|
||||
JSValue JS_CellRound (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_round (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, round (d));
|
||||
}
|
||||
|
||||
/* C API: trunc(num) - truncate towards zero */
|
||||
JSValue JS_CellTrunc (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_trunc (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, trunc (d));
|
||||
}
|
||||
|
||||
/* C API: whole(num) - integer part */
|
||||
JSValue JS_CellWhole (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_whole (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, trunc (d));
|
||||
}
|
||||
|
||||
/* C API: fraction(num) - fractional part */
|
||||
JSValue JS_CellFraction (JSContext *ctx, JSValue num) {
|
||||
return js_cell_number_fraction (ctx, JS_NULL, 1, &num);
|
||||
double d;
|
||||
if (js_cell_read_number_strict (num, &d) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, d - trunc (d));
|
||||
}
|
||||
|
||||
/* C API: min(a, b) - minimum of two numbers */
|
||||
JSValue JS_CellMin (JSContext *ctx, JSValue a, JSValue b) {
|
||||
JSValue argv[2] = { a, b };
|
||||
return js_cell_number_min (ctx, JS_NULL, 2, argv);
|
||||
double da, db;
|
||||
if (js_cell_read_number_strict (a, &da) < 0) return JS_NULL;
|
||||
if (js_cell_read_number_strict (b, &db) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, da < db ? da : db);
|
||||
}
|
||||
|
||||
/* C API: max(a, b) - maximum of two numbers */
|
||||
JSValue JS_CellMax (JSContext *ctx, JSValue a, JSValue b) {
|
||||
JSValue argv[2] = { a, b };
|
||||
return js_cell_number_max (ctx, JS_NULL, 2, argv);
|
||||
double da, db;
|
||||
if (js_cell_read_number_strict (a, &da) < 0) return JS_NULL;
|
||||
if (js_cell_read_number_strict (b, &db) < 0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx, da > db ? da : db);
|
||||
}
|
||||
|
||||
/* C API: remainder(a, b) - remainder after division */
|
||||
JSValue JS_CellRemainder (JSContext *ctx, JSValue a, JSValue b) {
|
||||
JSValue argv[2] = { a, b };
|
||||
return js_cell_number_remainder (ctx, JS_NULL, 2, argv);
|
||||
double dividend, divisor;
|
||||
if (js_cell_read_number_strict (a, ÷nd) < 0) return JS_NULL;
|
||||
if (js_cell_read_number_strict (b, &divisor) < 0) return JS_NULL;
|
||||
if (divisor == 0.0) return JS_NULL;
|
||||
return js_cell_number_from_double (ctx,
|
||||
dividend - (trunc (dividend / divisor) * divisor));
|
||||
}
|
||||
|
||||
/* Object functions */
|
||||
@@ -11374,7 +11431,7 @@ static void JS_AddIntrinsicBaseObjects (JSContext *ctx) {
|
||||
js_set_global_cfunc(ctx, "filter", js_cell_array_filter, 2);
|
||||
js_set_global_cfunc(ctx, "sort", js_cell_array_sort, 2);
|
||||
|
||||
/* Number utility functions */
|
||||
/* Number intrinsics: direct calls lower to mcode; globals remain for first-class use. */
|
||||
js_set_global_cfunc(ctx, "whole", js_cell_number_whole, 1);
|
||||
js_set_global_cfunc(ctx, "fraction", js_cell_number_fraction, 1);
|
||||
js_set_global_cfunc(ctx, "floor", js_cell_number_floor, 2);
|
||||
|
||||
Reference in New Issue
Block a user