60 |
#include "jsparse.h" |
#include "jsparse.h" |
61 |
#include "jsscope.h" |
#include "jsscope.h" |
62 |
#include "jsscript.h" |
#include "jsscript.h" |
63 |
|
#include "jsstaticcheck.h" |
64 |
#include "jsstr.h" |
#include "jsstr.h" |
65 |
|
|
66 |
#include "jsautooplen.h" |
#include "jsautooplen.h" |
125 |
if (!code) |
if (!code) |
126 |
break; |
break; |
127 |
memcpy(code, script->code, nbytes); |
memcpy(code, script->code, nbytes); |
128 |
JS_CLEAR_GSN_CACHE(cx); |
JS_PURGE_GSN_CACHE(cx); |
129 |
} |
} |
130 |
code[trap->pc - script->code] = trap->op; |
code[trap->pc - script->code] = trap->op; |
131 |
} |
} |
437 |
if (wp->object == obj) { |
if (wp->object == obj) { |
438 |
TRACE_SCOPE_PROPERTY(trc, wp->sprop); |
TRACE_SCOPE_PROPERTY(trc, wp->sprop); |
439 |
if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) { |
if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) { |
440 |
JS_CALL_OBJECT_TRACER(trc, (JSObject *)wp->setter, |
JS_CALL_OBJECT_TRACER(trc, js_CastAsObject(wp->setter), |
441 |
"wp->setter"); |
"wp->setter"); |
442 |
} |
} |
443 |
JS_SET_TRACING_NAME(trc, "wp->closure"); |
JS_SET_TRACING_NAME(trc, "wp->closure"); |
583 |
JSFunction *fun; |
JSFunction *fun; |
584 |
JSScript *script; |
JSScript *script; |
585 |
JSBool injectFrame; |
JSBool injectFrame; |
586 |
uintN nslots; |
uintN nslots, slotsStart; |
587 |
jsval smallv[5]; |
jsval smallv[5]; |
588 |
jsval *argv; |
jsval *argv; |
589 |
JSStackFrame frame; |
JSStackFrame frame; |
602 |
script = NULL; |
script = NULL; |
603 |
} |
} |
604 |
|
|
605 |
nslots = 2; |
slotsStart = nslots = 2; |
606 |
injectFrame = JS_TRUE; |
injectFrame = JS_TRUE; |
607 |
if (fun) { |
if (fun) { |
608 |
nslots += FUN_MINARGS(fun); |
nslots += FUN_MINARGS(fun); |
610 |
nslots += fun->u.n.extra; |
nslots += fun->u.n.extra; |
611 |
injectFrame = !(fun->flags & JSFUN_FAST_NATIVE); |
injectFrame = !(fun->flags & JSFUN_FAST_NATIVE); |
612 |
} |
} |
613 |
|
|
614 |
|
slotsStart = nslots; |
615 |
} |
} |
616 |
|
if (script) |
617 |
|
nslots += script->nslots; |
618 |
|
|
619 |
if (injectFrame) { |
if (injectFrame) { |
620 |
if (nslots <= JS_ARRAY_LENGTH(smallv)) { |
if (nslots <= JS_ARRAY_LENGTH(smallv)) { |
635 |
memset(&frame, 0, sizeof(frame)); |
memset(&frame, 0, sizeof(frame)); |
636 |
frame.script = script; |
frame.script = script; |
637 |
frame.regs = NULL; |
frame.regs = NULL; |
638 |
|
frame.callee = closure; |
639 |
|
frame.fun = fun; |
640 |
|
frame.argv = argv + 2; |
641 |
|
frame.down = js_GetTopStackFrame(cx); |
642 |
|
frame.scopeChain = OBJ_GET_PARENT(cx, closure); |
643 |
|
if (script && script->nslots) |
644 |
|
frame.slots = argv + slotsStart; |
645 |
if (script) { |
if (script) { |
646 |
JS_ASSERT(script->length >= JSOP_STOP_LENGTH); |
JS_ASSERT(script->length >= JSOP_STOP_LENGTH); |
647 |
regs.pc = script->code + script->length |
regs.pc = script->code + script->length |
648 |
- JSOP_STOP_LENGTH; |
- JSOP_STOP_LENGTH; |
649 |
regs.sp = NULL; |
regs.sp = NULL; |
650 |
frame.regs = ®s; |
frame.regs = ®s; |
651 |
|
if (fun && |
652 |
|
JSFUN_HEAVYWEIGHT_TEST(fun->flags) && |
653 |
|
!js_GetCallObject(cx, &frame)) { |
654 |
|
if (argv != smallv) |
655 |
|
JS_free(cx, argv); |
656 |
|
DBG_LOCK(rt); |
657 |
|
DropWatchPointAndUnlock(cx, wp, JSWP_HELD); |
658 |
|
return JS_FALSE; |
659 |
|
} |
660 |
} |
} |
|
frame.callee = closure; |
|
|
frame.fun = fun; |
|
|
frame.argv = argv + 2; |
|
|
frame.down = cx->fp; |
|
|
frame.scopeChain = OBJ_GET_PARENT(cx, closure); |
|
661 |
|
|
662 |
cx->fp = &frame; |
cx->fp = &frame; |
663 |
} |
} |
667 |
#endif |
#endif |
668 |
ok = !wp->setter || |
ok = !wp->setter || |
669 |
((sprop->attrs & JSPROP_SETTER) |
((sprop->attrs & JSPROP_SETTER) |
670 |
? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter), |
? js_InternalCall(cx, obj, |
671 |
|
js_CastAsObjectJSVal(wp->setter), |
672 |
1, vp, vp) |
1, vp, vp) |
673 |
: wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp)); |
: wp->setter(cx, obj, userid, vp)); |
674 |
if (injectFrame) { |
if (injectFrame) { |
675 |
/* Evil code can cause us to have an arguments object. */ |
/* Evil code can cause us to have an arguments object. */ |
676 |
if (frame.callobj) |
if (frame.callobj) |
691 |
return JS_TRUE; |
return JS_TRUE; |
692 |
} |
} |
693 |
|
|
694 |
JSBool |
JS_REQUIRES_STACK JSBool |
695 |
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, |
js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, |
696 |
jsval *rval) |
jsval *rval) |
697 |
{ |
{ |
700 |
jsval userid; |
jsval userid; |
701 |
|
|
702 |
funobj = JSVAL_TO_OBJECT(argv[-2]); |
funobj = JSVAL_TO_OBJECT(argv[-2]); |
|
JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass); |
|
703 |
wrapper = GET_FUNCTION_PRIVATE(cx, funobj); |
wrapper = GET_FUNCTION_PRIVATE(cx, funobj); |
704 |
userid = ATOM_KEY(wrapper->atom); |
userid = ATOM_KEY(wrapper->atom); |
705 |
*rval = argv[0]; |
*rval = argv[0]; |
725 |
atom = NULL; |
atom = NULL; |
726 |
} |
} |
727 |
wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0, |
wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0, |
728 |
OBJ_GET_PARENT(cx, (JSObject *)setter), |
OBJ_GET_PARENT(cx, js_CastAsObject(setter)), |
729 |
atom); |
atom); |
730 |
if (!wrapper) |
if (!wrapper) |
731 |
return NULL; |
return NULL; |
732 |
return (JSPropertyOp) FUN_OBJECT(wrapper); |
return js_CastAsPropertyOp(FUN_OBJECT(wrapper)); |
733 |
} |
} |
734 |
|
|
735 |
JS_PUBLIC_API(JSBool) |
JS_PUBLIC_API(JSBool) |
751 |
return JS_FALSE; |
return JS_FALSE; |
752 |
} |
} |
753 |
|
|
754 |
if (JSVAL_IS_INT(idval)) |
if (JSVAL_IS_INT(idval)) { |
755 |
propid = INT_JSVAL_TO_JSID(idval); |
propid = INT_JSVAL_TO_JSID(idval); |
756 |
else if (!js_ValueToStringId(cx, idval, &propid)) |
} else { |
757 |
return JS_FALSE; |
if (!js_ValueToStringId(cx, idval, &propid)) |
758 |
|
return JS_FALSE; |
759 |
|
CHECK_FOR_STRING_INDEX(propid); |
760 |
|
} |
761 |
|
|
762 |
if (!js_LookupProperty(cx, obj, propid, &pobj, &prop)) |
if (!js_LookupProperty(cx, obj, propid, &pobj, &prop)) |
763 |
return JS_FALSE; |
return JS_FALSE; |
994 |
JS_PUBLIC_API(JSStackFrame *) |
JS_PUBLIC_API(JSStackFrame *) |
995 |
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp) |
JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp) |
996 |
{ |
{ |
997 |
*iteratorp = (*iteratorp == NULL) ? cx->fp : (*iteratorp)->down; |
*iteratorp = (*iteratorp == NULL) ? js_GetTopStackFrame(cx) : (*iteratorp)->down; |
998 |
return *iteratorp; |
return *iteratorp; |
999 |
} |
} |
1000 |
|
|
1013 |
JS_PUBLIC_API(JSStackFrame *) |
JS_PUBLIC_API(JSStackFrame *) |
1014 |
JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp) |
JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp) |
1015 |
{ |
{ |
1016 |
if (!fp) |
return js_GetScriptedCaller(cx, fp); |
|
fp = cx->fp; |
|
|
while (fp) { |
|
|
if (fp->script) |
|
|
return fp; |
|
|
fp = fp->down; |
|
|
} |
|
|
return NULL; |
|
1017 |
} |
} |
1018 |
|
|
1019 |
JS_PUBLIC_API(JSPrincipals *) |
JS_PUBLIC_API(JSPrincipals *) |
1124 |
* XXX ill-defined: null return here means error was reported, unlike a |
* XXX ill-defined: null return here means error was reported, unlike a |
1125 |
* null returned above or in the #else |
* null returned above or in the #else |
1126 |
*/ |
*/ |
1127 |
return js_GetCallObject(cx, fp, NULL); |
return js_GetCallObject(cx, fp); |
1128 |
} |
} |
1129 |
|
|
1130 |
JS_PUBLIC_API(JSObject *) |
JS_PUBLIC_API(JSObject *) |
1136 |
return fp->thisp; |
return fp->thisp; |
1137 |
|
|
1138 |
/* js_ComputeThis gets confused if fp != cx->fp, so set it aside. */ |
/* js_ComputeThis gets confused if fp != cx->fp, so set it aside. */ |
1139 |
if (cx->fp != fp) { |
if (js_GetTopStackFrame(cx) != fp) { |
1140 |
afp = cx->fp; |
afp = cx->fp; |
1141 |
if (afp) { |
if (afp) { |
1142 |
afp->dormantNext = cx->dormantFrameChain; |
afp->dormantNext = cx->dormantFrameChain; |
1171 |
if (!fp->fun) |
if (!fp->fun) |
1172 |
return NULL; |
return NULL; |
1173 |
|
|
1174 |
JS_ASSERT(OBJ_GET_CLASS(cx, fp->callee) == &js_FunctionClass); |
JS_ASSERT(HAS_FUNCTION_CLASS(fp->callee)); |
1175 |
JS_ASSERT(OBJ_GET_PRIVATE(cx, fp->callee) == fp->fun); |
JS_ASSERT(OBJ_GET_PRIVATE(cx, fp->callee) == fp->fun); |
1176 |
return fp->callee; |
return fp->callee; |
1177 |
} |
} |
1257 |
const char *filename, uintN lineno, |
const char *filename, uintN lineno, |
1258 |
jsval *rval) |
jsval *rval) |
1259 |
{ |
{ |
1260 |
|
JS_ASSERT_NOT_ON_TRACE(cx); |
1261 |
|
|
1262 |
JSObject *scobj; |
JSObject *scobj; |
1263 |
JSScript *script; |
JSScript *script; |
1264 |
JSBool ok; |
JSBool ok; |
1267 |
if (!scobj) |
if (!scobj) |
1268 |
return JS_FALSE; |
return JS_FALSE; |
1269 |
|
|
1270 |
script = js_CompileScript(cx, scobj, fp, JS_StackFramePrincipals(cx, fp), |
/* |
1271 |
TCF_COMPILE_N_GO | |
* NB: This function breaks the assumption that the compiler can see all |
1272 |
TCF_PUT_STATIC_DEPTH(fp->script->staticDepth + 1), |
* calls and properly compute a static level. In order to get around this, |
1273 |
chars, length, NULL, |
* we use a static level that will cause us not to attempt to optimize |
1274 |
filename, lineno); |
* variable references made by this frame. |
1275 |
|
*/ |
1276 |
|
script = JSCompiler::compileScript(cx, scobj, fp, JS_StackFramePrincipals(cx, fp), |
1277 |
|
TCF_COMPILE_N_GO | |
1278 |
|
TCF_PUT_STATIC_LEVEL(JS_DISPLAY_SIZE), |
1279 |
|
chars, length, NULL, |
1280 |
|
filename, lineno); |
1281 |
|
|
1282 |
if (!script) |
if (!script) |
1283 |
return JS_FALSE; |
return JS_FALSE; |
1284 |
|
|
1285 |
|
JSStackFrame *displayCopy[JS_DISPLAY_SIZE]; |
1286 |
|
if (cx->fp != fp) { |
1287 |
|
memcpy(displayCopy, cx->display, sizeof displayCopy); |
1288 |
|
|
1289 |
|
/* |
1290 |
|
* Set up cx->display as it would have been when fp was active. |
1291 |
|
* |
1292 |
|
* NB: To reconstruct cx->display for fp, we have to follow the frame |
1293 |
|
* chain from oldest to youngest, in the opposite direction to its |
1294 |
|
* single linkge. To avoid the obvious recursive reversal algorithm, |
1295 |
|
* which might use too much stack, we reverse in place and reverse |
1296 |
|
* again as we reconstruct the display. This is safe because cx is |
1297 |
|
* thread-local and we can't cause GC until the call to js_Execute |
1298 |
|
* below. |
1299 |
|
*/ |
1300 |
|
JSStackFrame *fp2 = fp, *last = NULL; |
1301 |
|
while (fp2) { |
1302 |
|
JSStackFrame *next = fp2->down; |
1303 |
|
fp2->down = last; |
1304 |
|
last = fp2; |
1305 |
|
fp2 = next; |
1306 |
|
} |
1307 |
|
|
1308 |
|
fp2 = last; |
1309 |
|
last = NULL; |
1310 |
|
while (fp2) { |
1311 |
|
JSStackFrame *next = fp2->down; |
1312 |
|
fp2->down = last; |
1313 |
|
last = fp2; |
1314 |
|
|
1315 |
|
JSScript *script = fp2->script; |
1316 |
|
if (script && script->staticLevel < JS_DISPLAY_SIZE) |
1317 |
|
cx->display[script->staticLevel] = fp2; |
1318 |
|
fp2 = next; |
1319 |
|
} |
1320 |
|
} |
1321 |
|
|
1322 |
ok = js_Execute(cx, scobj, script, fp, JSFRAME_DEBUGGER | JSFRAME_EVAL, |
ok = js_Execute(cx, scobj, script, fp, JSFRAME_DEBUGGER | JSFRAME_EVAL, |
1323 |
rval); |
rval); |
1324 |
|
|
1325 |
|
if (cx->fp != fp) |
1326 |
|
memcpy(cx->display, displayCopy, sizeof cx->display); |
1327 |
js_DestroyScript(cx, script); |
js_DestroyScript(cx, script); |
1328 |
return ok; |
return ok; |
1329 |
} |
} |
1469 |
return JS_TRUE; |
return JS_TRUE; |
1470 |
} |
} |
1471 |
|
|
1472 |
n = STOBJ_NSLOTS(obj); |
n = scope->entryCount; |
|
if (n > scope->entryCount) |
|
|
n = scope->entryCount; |
|
1473 |
pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc)); |
pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc)); |
1474 |
if (!pd) |
if (!pd) |
1475 |
return JS_FALSE; |
return JS_FALSE; |
1692 |
JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp) |
JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp) |
1693 |
{ |
{ |
1694 |
if (!fp) |
if (!fp) |
1695 |
fp = cx->fp; |
fp = js_GetTopStackFrame(cx); |
1696 |
while (fp) { |
while (fp) { |
1697 |
if (fp->script) |
if (fp->script) |
1698 |
return JS_GetScriptFilenameFlags(fp->script); |
return JS_GetScriptFilenameFlags(fp->script); |
1808 |
{ |
{ |
1809 |
if (!JS_StartChudRemote()) { |
if (!JS_StartChudRemote()) { |
1810 |
JS_ReportError(cx, "Error starting CHUD."); |
JS_ReportError(cx, "Error starting CHUD."); |
1811 |
|
return JS_FALSE; |
1812 |
} |
} |
1813 |
|
|
1814 |
return JS_TRUE; |
return JS_TRUE; |
1820 |
{ |
{ |
1821 |
if (!JS_StopChudRemote()) { |
if (!JS_StopChudRemote()) { |
1822 |
JS_ReportError(cx, "Error stopping CHUD."); |
JS_ReportError(cx, "Error stopping CHUD."); |
1823 |
|
return JS_FALSE; |
1824 |
} |
} |
1825 |
|
|
1826 |
return JS_TRUE; |
return JS_TRUE; |
1832 |
{ |
{ |
1833 |
if (!JS_ConnectShark()) { |
if (!JS_ConnectShark()) { |
1834 |
JS_ReportError(cx, "Error connecting to Shark."); |
JS_ReportError(cx, "Error connecting to Shark."); |
1835 |
|
return JS_FALSE; |
1836 |
} |
} |
1837 |
|
|
1838 |
return JS_TRUE; |
return JS_TRUE; |
1844 |
{ |
{ |
1845 |
if (!JS_DisconnectShark()) { |
if (!JS_DisconnectShark()) { |
1846 |
JS_ReportError(cx, "Error disconnecting from Shark."); |
JS_ReportError(cx, "Error disconnecting from Shark."); |
1847 |
|
return JS_FALSE; |
1848 |
} |
} |
1849 |
|
|
1850 |
return JS_TRUE; |
return JS_TRUE; |
1860 |
js_StartCallgrind(JSContext *cx, JSObject *obj, |
js_StartCallgrind(JSContext *cx, JSObject *obj, |
1861 |
uintN argc, jsval *argv, jsval *rval) |
uintN argc, jsval *argv, jsval *rval) |
1862 |
{ |
{ |
1863 |
CALLGRIND_START_INSTRUMENTATION; |
CALLGRIND_START_INSTRUMENTATION; |
1864 |
CALLGRIND_ZERO_STATS; |
CALLGRIND_ZERO_STATS; |
1865 |
return JS_TRUE; |
return JS_TRUE; |
1866 |
} |
} |
1930 |
js_StartVtune(JSContext *cx, JSObject *obj, |
js_StartVtune(JSContext *cx, JSObject *obj, |
1931 |
uintN argc, jsval *argv, jsval *rval) |
uintN argc, jsval *argv, jsval *rval) |
1932 |
{ |
{ |
1933 |
VTUNE_EVENT events[] = { |
VTUNE_EVENT events[] = { |
1934 |
{ 1000000, 0, 0, 0, "CPU_CLK_UNHALTED.CORE" }, |
{ 1000000, 0, 0, 0, "CPU_CLK_UNHALTED.CORE" }, |
1935 |
{ 1000000, 0, 0, 0, "INST_RETIRED.ANY" }, |
{ 1000000, 0, 0, 0, "INST_RETIRED.ANY" }, |
1936 |
}; |
}; |
1937 |
|
|
1938 |
U32 n_events = sizeof(events) / sizeof(VTUNE_EVENT); |
U32 n_events = sizeof(events) / sizeof(VTUNE_EVENT); |
1940 |
JSString *str; |
JSString *str; |
1941 |
U32 status; |
U32 status; |
1942 |
|
|
1943 |
VTUNE_SAMPLING_PARAMS params = { |
VTUNE_SAMPLING_PARAMS params = |
1944 |
sizeof(VTUNE_SAMPLING_PARAMS), |
sizeof(VTUNE_SAMPLING_PARAMS), |
1945 |
sizeof(VTUNE_EVENT), |
sizeof(VTUNE_EVENT), |
1946 |
0, 0, /* Reserved fields */ |
0, 0, /* Reserved fields */ |
1957 |
|
|
1958 |
if (argc > 0 && JSVAL_IS_STRING(argv[0])) { |
if (argc > 0 && JSVAL_IS_STRING(argv[0])) { |
1959 |
str = JSVAL_TO_STRING(argv[0]); |
str = JSVAL_TO_STRING(argv[0]); |
1960 |
params.tb5Filename = js_DeflateString(cx, |
params.tb5Filename = js_DeflateString(cx, |
1961 |
JSSTRING_CHARS(str), |
JSSTRING_CHARS(str), |
1962 |
JSSTRING_LENGTH(str)); |
JSSTRING_LENGTH(str)); |
1963 |
} |
} |
1964 |
|
|
1965 |
status = VTStartSampling(¶ms); |
status = VTStartSampling(¶ms); |
1966 |
|
|
1967 |
if (params.tb5Filename != default_filename) |
if (params.tb5Filename != default_filename) |
1968 |
JS_free(cx, params.tb5Filename); |
JS_free(cx, params.tb5Filename); |
1969 |
|
|
1970 |
if (status != 0) { |
if (status != 0) { |
1971 |
if (status == VTAPI_MULTIPLE_RUNS) |
if (status == VTAPI_MULTIPLE_RUNS) |
1972 |
VTStopSampling(0); |
VTStopSampling(0); |
1973 |
if (status < sizeof(vtuneErrorMessages)) |
if (status < sizeof(vtuneErrorMessages)) |
1974 |
JS_ReportError(cx, "Vtune setup error: %s", |
JS_ReportError(cx, "Vtune setup error: %s", |
1975 |
vtuneErrorMessages[status]); |
vtuneErrorMessages[status]); |
1976 |
else |
else |
1977 |
JS_ReportError(cx, "Vtune setup error: %d", |
JS_ReportError(cx, "Vtune setup error: %d", |
1978 |
status); |
status); |
1979 |
return JS_FALSE; |
return JS_FALSE; |
1980 |
} |
} |
1981 |
return JS_TRUE; |
return JS_TRUE; |
1988 |
U32 status = VTStopSampling(1); |
U32 status = VTStopSampling(1); |
1989 |
if (status) { |
if (status) { |
1990 |
if (status < sizeof(vtuneErrorMessages)) |
if (status < sizeof(vtuneErrorMessages)) |
1991 |
JS_ReportError(cx, "Vtune shutdown error: %s", |
JS_ReportError(cx, "Vtune shutdown error: %s", |
1992 |
vtuneErrorMessages[status]); |
vtuneErrorMessages[status]); |
1993 |
else |
else |
1994 |
JS_ReportError(cx, "Vtune shutdown error: %d", |
JS_ReportError(cx, "Vtune shutdown error: %d", |
1995 |
status); |
status); |
1996 |
return JS_FALSE; |
return JS_FALSE; |
1997 |
} |
} |