📄 swfdec_debugger.c
字号:
g_assert (dscript); g_signal_emit (debugger, signals[SCRIPT_REMOVED], 0, dscript); g_hash_table_remove (debugger->scripts, script);}typedef struct { GFunc func; gpointer data;} ForeachData;static voiddo_foreach (gpointer key, gpointer value, gpointer data){ ForeachData *fdata = data; fdata->func (value, fdata->data);}voidswfdec_debugger_foreach_script (SwfdecDebugger *debugger, GFunc func, gpointer data){ ForeachData fdata = { func, data }; g_hash_table_foreach (debugger->scripts, do_foreach, &fdata);}/*** BREAKPOINTS ***/typedef struct { SwfdecDebuggerScript * script; guint line;} Breakpoint;static voidswfdec_debugger_do_breakpoint (SwfdecDebugger *debugger, guint id){ SwfdecPlayer *player = SWFDEC_PLAYER (debugger); GList *walk; for (walk = player->roots; walk; walk = walk->next) { swfdec_movie_update (walk->data); } g_object_thaw_notify (G_OBJECT (debugger)); if (!swfdec_rect_is_empty (&player->invalid)) { double x, y, width, height; x = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x0); y = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y0); width = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x1 - player->invalid.x0); height = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y1 - player->invalid.y0); g_signal_emit_by_name (player, "invalidate", x, y, width, height); swfdec_rect_init_empty (&player->invalid); } g_signal_emit (debugger, signals[BREAKPOINT], 0, id); g_object_freeze_notify (G_OBJECT (debugger));}static JSTrapStatusswfdec_debugger_interrupt_cb (JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *debugger){ SwfdecDebuggerScript *dscript; guint line; if (!swfdec_debugger_get_current (debugger, &dscript, &line)) return JSTRAP_CONTINUE; if (dscript->commands[line].breakpoint) { swfdec_debugger_do_breakpoint (debugger, dscript->commands[line].breakpoint); } else if (SWFDEC_DEBUGGER (debugger)->stepping) { swfdec_debugger_do_breakpoint (debugger, 0); } return JSTRAP_CONTINUE;}static voidswfdec_debugger_update_interrupting (SwfdecDebugger *debugger){ guint i; gboolean should_interrupt = debugger->stepping; for (i = 0; i < debugger->breakpoints->len && !should_interrupt; i++) { Breakpoint *br = &g_array_index (debugger->breakpoints, Breakpoint, i); if (br->script) { should_interrupt = TRUE; break; } } if (should_interrupt) { JS_SetInterrupt (JS_GetRuntime (SWFDEC_PLAYER (debugger)->jscx), swfdec_debugger_interrupt_cb, debugger); } else { JS_ClearInterrupt (JS_GetRuntime (SWFDEC_PLAYER (debugger)->jscx), NULL, NULL); }}guintswfdec_debugger_set_breakpoint (SwfdecDebugger *debugger, SwfdecDebuggerScript *script, guint line){ guint i; Breakpoint *br = NULL; g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), 0); g_return_val_if_fail (script != NULL, 0); g_return_val_if_fail (line < script->n_commands, 0); if (debugger->breakpoints == NULL) { debugger->breakpoints = g_array_new (FALSE, FALSE, sizeof (Breakpoint)); } if (script->commands[line].breakpoint != 0) return script->commands[line].breakpoint; for (i = 0; i < debugger->breakpoints->len; i++) { br = &g_array_index (debugger->breakpoints, Breakpoint, i); if (br->script == NULL) break; br = NULL; } if (br == NULL) { g_array_set_size (debugger->breakpoints, debugger->breakpoints->len + 1); br = &g_array_index (debugger->breakpoints, Breakpoint, debugger->breakpoints->len - 1); } br->script = script; br->line = line; script->commands[line].breakpoint = i + 1; swfdec_debugger_update_interrupting (debugger); g_signal_emit (debugger, signals[BREAKPOINT_ADDED], 0, i + 1); return i + 1;}voidswfdec_debugger_unset_breakpoint (SwfdecDebugger *debugger, guint id){ Breakpoint *br; g_return_if_fail (SWFDEC_IS_DEBUGGER (debugger)); g_return_if_fail (id > 0); if (debugger->breakpoints == NULL) return; if (id > debugger->breakpoints->len) return; br = &g_array_index (debugger->breakpoints, Breakpoint, id - 1); if (br->script == NULL) return; g_signal_emit (debugger, signals[BREAKPOINT_REMOVED], 0, id); br->script->commands[br->line].breakpoint = 0; br->script = NULL; swfdec_debugger_update_interrupting (debugger);}static gbooleanswfdec_debugger_get_from_js (SwfdecDebugger *debugger, SwfdecScript *script, jsbytecode *pc, SwfdecDebuggerScript **script_out, guint *line_out){ guint line; SwfdecDebuggerScript *dscript = swfdec_debugger_get_script (debugger, script); if (dscript == NULL) return FALSE; for (line = 0; line < dscript->n_commands; line++) { if (pc == dscript->commands[line].code) { if (script_out) *script_out = dscript; if (line_out) *line_out = line; return TRUE; } if (pc < (jsbytecode *) dscript->commands[line].code) return FALSE; } return FALSE;}gbooleanswfdec_debugger_get_current (SwfdecDebugger *debugger, SwfdecDebuggerScript **dscript, guint *line){ JSStackFrame *frame = NULL; JSContext *cx; jsbytecode *pc; cx = SWFDEC_PLAYER (debugger)->jscx; JS_FrameIterator (cx, &frame); if (frame == NULL) return FALSE; if (frame->swf == NULL) return FALSE; pc = JS_GetFramePC (cx, frame); return swfdec_debugger_get_from_js (debugger, frame->swf, pc, dscript, line);}gbooleanswfdec_debugger_get_breakpoint (SwfdecDebugger *debugger, guint id, SwfdecDebuggerScript **script, guint *line){ Breakpoint *br; g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), FALSE); g_return_val_if_fail (id > 0, FALSE); if (debugger->breakpoints == NULL) return FALSE; if (id > debugger->breakpoints->len) return FALSE; br = &g_array_index (debugger->breakpoints, Breakpoint, id - 1); if (br->script == NULL) return FALSE; if (script) *script = br->script; if (line) *line = br->line; return TRUE;}guintswfdec_debugger_get_n_breakpoints (SwfdecDebugger *debugger){ g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), 0); if (debugger->breakpoints == NULL) return 0; return debugger->breakpoints->len;}voidswfdec_debugger_set_stepping (SwfdecDebugger *debugger, gboolean stepping){ g_return_if_fail (SWFDEC_IS_DEBUGGER (debugger)); if (debugger->stepping == stepping) return; debugger->stepping = stepping;}gbooleanswfdec_debugger_get_stepping (SwfdecDebugger *debugger){ g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), FALSE); return debugger->stepping;}const char *swfdec_debugger_run (SwfdecDebugger *debugger, const char *command){ SwfdecPlayer *player; GList *walk; jsval rval; const char *ret; g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), NULL); g_return_val_if_fail (command != NULL, NULL); player = SWFDEC_PLAYER (debugger); g_object_freeze_notify (G_OBJECT (debugger)); if (swfdec_js_run (player, command, &rval)) { ret = swfdec_js_to_string (player->jscx, rval); } else { ret = NULL; } for (walk = player->roots; walk; walk = walk->next) { swfdec_movie_update (walk->data); } if (!swfdec_rect_is_empty (&player->invalid)) { double x, y, width, height; x = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x0); y = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y0); width = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x1 - player->invalid.x0); height = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y1 - player->invalid.y0); g_signal_emit_by_name (player, "invalidate", x, y, width, height); swfdec_rect_init_empty (&player->invalid); } g_object_thaw_notify (G_OBJECT (debugger)); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -