mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Add Array (generic) join builtin, plus (not yet used) optional this-class guarding for builtins.
This commit is contained in:
parent
5bbc609a8b
commit
0099753ff4
@ -49,6 +49,7 @@ BUILTIN2(Math_pow, F, F, F, jsdouble, jsdouble, jsdouble,
|
||||
BUILTIN1(Math_sqrt, F, F, jsdouble, jsdouble, 1, 1)
|
||||
BUILTIN1(Math_floor, F, F, jsdouble, jsdouble, 1, 1)
|
||||
BUILTIN4(Array_dense_setelem, LO, LO, LO, LO, LO, bool, JSContext*, JSObject*, jsint, jsval, 1, 1)
|
||||
BUILTIN3(Array_p_join, LO, LO, LO, LO, JSString*, JSContext*, JSObject*, JSString*, 1, 1)
|
||||
BUILTIN4(String_p_substring, LO, LO, LO, LO, LO, JSString*, JSContext*, JSString*, jsint, jsint, 1, 1)
|
||||
BUILTIN3(String_p_substring_1, LO, LO, LO, LO, JSString*, JSContext*, JSString*, jsint, 1, 1)
|
||||
BUILTIN3(FastConcatStrings, LO, LO, LO, LO, JSString*, JSContext*, JSString*, JSString*, 1, 1)
|
||||
|
@ -1183,20 +1183,14 @@ out_bad:
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
enum ArrayToStringOp {
|
||||
TO_STRING,
|
||||
TO_LOCALE_STRING,
|
||||
TO_SOURCE
|
||||
};
|
||||
|
||||
/*
|
||||
* When op is TO_STRING or TO_LOCALE_STRING sep indicates a separator to use
|
||||
* or "," when sep is NULL.
|
||||
* When op is TO_SOURCE sep must be NULL.
|
||||
*/
|
||||
static JSBool
|
||||
array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
|
||||
JSString *sep, jsval *rval)
|
||||
JSBool
|
||||
js_array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
|
||||
JSString *sep, jsval *rval)
|
||||
{
|
||||
JSBool ok, hole;
|
||||
jsuint length, index;
|
||||
@ -1414,7 +1408,7 @@ array_toSource(JSContext *cx, uintN argc, jsval *vp)
|
||||
!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
return array_join_sub(cx, obj, TO_SOURCE, NULL, vp);
|
||||
return js_array_join_sub(cx, obj, TO_SOURCE, NULL, vp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1428,7 +1422,7 @@ array_toString(JSContext *cx, uintN argc, jsval *vp)
|
||||
!JS_InstanceOf(cx, obj, &js_ArrayClass, vp + 2)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
return array_join_sub(cx, obj, TO_STRING, NULL, vp);
|
||||
return js_array_join_sub(cx, obj, TO_STRING, NULL, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -1446,7 +1440,7 @@ array_toLocaleString(JSContext *cx, uintN argc, jsval *vp)
|
||||
* Passing comma here as the separator. Need a way to get a
|
||||
* locale-specific version.
|
||||
*/
|
||||
return array_join_sub(cx, obj, TO_LOCALE_STRING, NULL, vp);
|
||||
return js_array_join_sub(cx, obj, TO_LOCALE_STRING, NULL, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -1505,8 +1499,8 @@ InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector,
|
||||
/*
|
||||
* Perl-inspired join, reverse, and sort.
|
||||
*/
|
||||
static JSBool
|
||||
array_join(JSContext *cx, uintN argc, jsval *vp)
|
||||
JSBool
|
||||
js_array_join(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
JSString *str;
|
||||
JSObject *obj;
|
||||
@ -1520,7 +1514,7 @@ array_join(JSContext *cx, uintN argc, jsval *vp)
|
||||
vp[2] = STRING_TO_JSVAL(str);
|
||||
}
|
||||
obj = JS_THIS_OBJECT(cx, vp);
|
||||
return obj && array_join_sub(cx, obj, TO_STRING, str, vp);
|
||||
return obj && js_array_join_sub(cx, obj, TO_STRING, str, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -2880,7 +2874,7 @@ static JSFunctionSpec array_methods[] = {
|
||||
JS_FN(js_toLocaleString_str,array_toLocaleString,0,0),
|
||||
|
||||
/* Perl-ish methods. */
|
||||
JS_FN("join", array_join, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("join", js_array_join, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("reverse", array_reverse, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("sort", array_sort, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("push", array_push, 1,JSFUN_GENERIC_NATIVE),
|
||||
|
@ -123,6 +123,19 @@ extern JSBool
|
||||
js_ArrayInfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
#endif
|
||||
|
||||
extern JSBool
|
||||
js_array_join(JSContext *cx, uintN argc, jsval *vp);
|
||||
|
||||
enum ArrayToStringOp {
|
||||
TO_STRING,
|
||||
TO_LOCALE_STRING,
|
||||
TO_SOURCE
|
||||
};
|
||||
|
||||
extern JSBool
|
||||
js_array_join_sub(JSContext *cx, JSObject *obj, enum ArrayToStringOp op,
|
||||
JSString *sep, jsval *rval);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsarray_h___ */
|
||||
|
@ -195,6 +195,16 @@ js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
|
||||
return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(i), &v) ? true : false;
|
||||
}
|
||||
|
||||
JSString* FASTCALL
|
||||
js_Array_p_join(JSContext* cx, JSObject* obj, JSString *str)
|
||||
{
|
||||
jsval v;
|
||||
if (!js_array_join_sub(cx, obj, TO_STRING, str, &v))
|
||||
return NULL;
|
||||
JS_ASSERT(JSVAL_IS_STRING(v));
|
||||
return JSVAL_TO_STRING(v);
|
||||
}
|
||||
|
||||
JSString* FASTCALL
|
||||
js_String_p_substring(JSContext* cx, JSString* str, jsint begin, jsint end)
|
||||
{
|
||||
|
@ -3246,19 +3246,21 @@ TraceRecorder::record_JSOP_CALL()
|
||||
const char *prefix;
|
||||
const char *argtypes;
|
||||
JSTNErrType errtype;
|
||||
JSClass *tclasp;
|
||||
} knownNatives[] = {
|
||||
{ js_math_sin, F_Math_sin, "", "d", INFALLIBLE, },
|
||||
{ js_math_cos, F_Math_cos, "", "d", INFALLIBLE, },
|
||||
{ js_math_pow, F_Math_pow, "", "dd", INFALLIBLE, },
|
||||
{ js_math_sqrt, F_Math_sqrt, "", "d", INFALLIBLE, },
|
||||
{ js_math_floor, F_Math_floor, "", "d", INFALLIBLE, },
|
||||
{ js_str_substring, F_String_p_substring, "TC", "ii", FAIL_NULL, },
|
||||
{ js_str_substring, F_String_p_substring_1, "TC", "i", FAIL_NULL, },
|
||||
{ js_str_fromCharCode, F_String_fromCharCode, "C", "i", FAIL_NULL, },
|
||||
{ js_str_charCodeAt, F_String_p_charCodeAt, "T", "i", FAIL_NEG, },
|
||||
{ js_str_charAt, F_String_getelem, "TC", "i", FAIL_NULL, },
|
||||
{ js_math_random, F_Math_random, "R", "", INFALLIBLE, },
|
||||
{ js_str_concat, F_String_p_concat_1int, "TC", "i", FAIL_NULL, },
|
||||
{ js_math_sin, F_Math_sin, "", "d", INFALLIBLE, NULL },
|
||||
{ js_math_cos, F_Math_cos, "", "d", INFALLIBLE, NULL },
|
||||
{ js_math_pow, F_Math_pow, "", "dd", INFALLIBLE, NULL },
|
||||
{ js_math_sqrt, F_Math_sqrt, "", "d", INFALLIBLE, NULL },
|
||||
{ js_math_floor, F_Math_floor, "", "d", INFALLIBLE, NULL },
|
||||
{ js_str_substring, F_String_p_substring, "TC", "ii", FAIL_NULL, NULL },
|
||||
{ js_str_substring, F_String_p_substring_1, "TC", "i", FAIL_NULL, NULL },
|
||||
{ js_str_fromCharCode, F_String_fromCharCode, "C", "i", FAIL_NULL, NULL },
|
||||
{ js_str_charCodeAt, F_String_p_charCodeAt, "T", "i", FAIL_NEG, NULL },
|
||||
{ js_str_charAt, F_String_getelem, "TC", "i", FAIL_NULL, NULL },
|
||||
{ js_math_random, F_Math_random, "R", "", INFALLIBLE, NULL },
|
||||
{ js_str_concat, F_String_p_concat_1int, "TC", "i", FAIL_NULL, NULL },
|
||||
{ js_array_join, F_Array_p_join, "TC", "s", FAIL_NULL, NULL },
|
||||
};
|
||||
|
||||
for (uintN i = 0; i < JS_ARRAY_LENGTH(knownNatives); i++) {
|
||||
@ -3275,7 +3277,14 @@ TraceRecorder::record_JSOP_CALL()
|
||||
LIns** argp = &args[argc + prefixc - 1];
|
||||
char argtype;
|
||||
|
||||
LIns* thisval_ins = stack(0 - (argc + 1));
|
||||
jsval& thisval = stackval(0 - (argc + 1));
|
||||
LIns* thisval_ins = get(&thisval);
|
||||
if (known->tclasp) {
|
||||
if (JSVAL_IS_PRIMITIVE(thisval))
|
||||
ABORT_TRACE("known native with class guard called on primitive this");
|
||||
if (!guardClass(JSVAL_TO_OBJECT(thisval), thisval_ins, known->tclasp))
|
||||
return false;
|
||||
}
|
||||
|
||||
#define HANDLE_PREFIX(i) \
|
||||
argtype = known->prefix[i]; \
|
||||
@ -3308,11 +3317,17 @@ TraceRecorder::record_JSOP_CALL()
|
||||
#define HANDLE_ARG(i) \
|
||||
argtype = known->argtypes[i]; \
|
||||
if (argtype == 'd' || argtype == 'i') { \
|
||||
if (!isNumber(stackval(-(i + 1)))) \
|
||||
jsval& arg = stackval(-(i + 1)); \
|
||||
if (!isNumber(arg)) \
|
||||
ABORT_TRACE("arg in position " #i " must be numeric"); \
|
||||
*argp = get(&stackval(-(i + 1))); \
|
||||
*argp = get(&arg); \
|
||||
if (argtype == 'i') \
|
||||
*argp = f2i(*argp); \
|
||||
} else if (argtype == 's') { \
|
||||
jsval& arg = stackval(-(i + 1)); \
|
||||
if (!JSVAL_IS_STRING(arg)) \
|
||||
ABORT_TRACE("arg in position " #i " must be a string"); \
|
||||
*argp = get(&arg); \
|
||||
} else { \
|
||||
JS_NOT_REACHED("unknown arg type"); \
|
||||
} \
|
||||
|
Loading…
Reference in New Issue
Block a user