📄 swfdec_as_interpret.c
字号:
static voidswfdec_action_decrement (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; val = swfdec_as_stack_peek (cx, 1); SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (cx, val) - 1);}static voidswfdec_action_increment (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; val = swfdec_as_stack_peek (cx, 1); SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_as_value_to_number (cx, val) + 1);}static voidswfdec_action_get_url (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecBits bits; char *url, *target; swfdec_bits_init_data (&bits, data, len); url = swfdec_bits_get_string_with_version (&bits, cx->version); target = swfdec_bits_get_string_with_version (&bits, cx->version); if (url == NULL || target == NULL) { SWFDEC_ERROR ("not enough data in GetURL"); g_free (url); g_free (target); return; } if (swfdec_bits_left (&bits)) { SWFDEC_WARNING ("leftover bytes in GetURL action"); } if (SWFDEC_IS_MOVIE (cx->frame->target)) swfdec_movie_load (SWFDEC_MOVIE (cx->frame->target), url, target, SWFDEC_LOADER_REQUEST_DEFAULT, NULL, 0); else SWFDEC_WARNING ("no movie to load"); g_free (url); g_free (target);}static voidswfdec_action_get_url2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ const char *target, *url; guint method; if (len != 1) { SWFDEC_ERROR ("GetURL2 requires 1 byte of data, not %u", len); return; } target = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1)); url = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2)); method = data[0] >> 6; if (method == 3) { SWFDEC_ERROR ("GetURL method 3 invalid"); method = 0; } if (data[0] & 2) { SWFDEC_FIXME ("implement LoadTarget"); } if (data[0] & 1) { SWFDEC_FIXME ("implement LoadVariables"); } if (SWFDEC_IS_MOVIE (cx->frame->target)) swfdec_movie_load (SWFDEC_MOVIE (cx->frame->target), url, target, method, NULL, 0); else SWFDEC_WARNING ("no movie to load"); swfdec_as_stack_pop_n (cx, 2);}static voidswfdec_action_string_add (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ const char *lval, *rval; rval = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1)); lval = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2)); lval = swfdec_as_str_concat (cx, lval, rval); SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_peek (cx, 2), lval); swfdec_as_stack_pop (cx);}static voidswfdec_action_push_duplicate (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ *swfdec_as_stack_push (cx) = *swfdec_as_stack_peek (cx, 1);}static voidswfdec_action_random_number (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ gint32 max; SwfdecAsValue *val; val = swfdec_as_stack_peek (cx, 1); max = swfdec_as_value_to_integer (cx, val); if (max <= 0) SWFDEC_AS_VALUE_SET_NUMBER (val, 0); else SWFDEC_AS_VALUE_SET_NUMBER (val, g_rand_int_range (cx->rand, 0, max));}static voidswfdec_action_old_compare (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ double l, r; gboolean cond; l = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 2)); r = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 1)); switch (action) { case SWFDEC_AS_ACTION_EQUALS: cond = l == r; break; case SWFDEC_AS_ACTION_LESS: cond = l < r; break; default: g_assert_not_reached (); return; } swfdec_as_stack_pop (cx); if (cx->version < 5) { SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), cond ? 1 : 0); } else { SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), cond); }}static voidswfdec_action_string_length (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ const char *s; SwfdecAsValue *v; v = swfdec_as_stack_peek (cx, 1); s = swfdec_as_value_to_string (cx, v); SWFDEC_AS_VALUE_SET_INT (v, g_utf8_strlen (s, -1)); }static voidswfdec_action_string_compare (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ const char *l, *r; gboolean cond; r = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1)); l = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2)); switch (action) { case SWFDEC_AS_ACTION_STRING_EQUALS: cond = l == r; break; case SWFDEC_AS_ACTION_STRING_LESS: cond = strcmp (l, r) < 0; break; default: g_assert_not_reached (); break; } swfdec_as_stack_pop (cx); if (cx->version < 5) { SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), cond ? 1 : 0); } else { SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), cond); }}static voidswfdec_action_equals2_5 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *rval, *lval; SwfdecAsValue rtmp, ltmp; SwfdecAsValueType ltype, rtype; double l, r; gboolean cond; rval = swfdec_as_stack_peek (cx, 1); lval = swfdec_as_stack_peek (cx, 2); rtmp = *rval; ltmp = *lval; swfdec_as_value_to_primitive (&rtmp); swfdec_as_value_to_primitive (<mp); ltype = ltmp.type; rtype = rtmp.type; /* get objects compared */ if (ltype == SWFDEC_AS_TYPE_OBJECT && rtype == SWFDEC_AS_TYPE_OBJECT) { SwfdecAsObject *lo = SWFDEC_AS_VALUE_GET_OBJECT (<mp); SwfdecAsObject *ro = SWFDEC_AS_VALUE_GET_OBJECT (&rtmp); if (!SWFDEC_IS_MOVIE (lo)) lo = SWFDEC_AS_VALUE_GET_OBJECT (lval); if (!SWFDEC_IS_MOVIE (ro)) ro = SWFDEC_AS_VALUE_GET_OBJECT (rval); if (SWFDEC_IS_MOVIE (lo) && SWFDEC_IS_MOVIE (ro)) { /* do nothing */ } else if (SWFDEC_IS_MOVIE (lo)) { swfdec_as_value_to_primitive (rval); rtype = rval->type; if (rtype != SWFDEC_AS_TYPE_OBJECT) { cond = FALSE; goto out; } ro = SWFDEC_AS_VALUE_GET_OBJECT (rval); } else if (SWFDEC_IS_MOVIE (ro)) { swfdec_as_value_to_primitive (lval); ltype = lval->type; if (ltype != SWFDEC_AS_TYPE_OBJECT) { cond = FALSE; goto out; } lo = SWFDEC_AS_VALUE_GET_OBJECT (lval); } cond = lo == ro; goto out; } /* compare strings */ if (ltype == SWFDEC_AS_TYPE_STRING && rtype == SWFDEC_AS_TYPE_STRING) { /* FIXME: flash 5 case insensitive? */ cond = SWFDEC_AS_VALUE_GET_STRING (<mp) == SWFDEC_AS_VALUE_GET_STRING (&rtmp); goto out; } /* convert to numbers */ if (SWFDEC_AS_VALUE_IS_OBJECT (<mp) && !SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (<mp))) { l = swfdec_as_value_to_number (cx, lval); } else { l = swfdec_as_value_to_number (cx, <mp); } if (SWFDEC_AS_VALUE_IS_OBJECT (&rtmp) && !SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (&rtmp))) { r = swfdec_as_value_to_number (cx, rval); } else { r = swfdec_as_value_to_number (cx, &rtmp); } /* get rid of undefined and null */ cond = rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL; if (ltype == SWFDEC_AS_TYPE_UNDEFINED || ltype == SWFDEC_AS_TYPE_NULL) { goto out; } else if (cond) { cond = FALSE; goto out; } /* else compare as numbers */ if (isnan (l) && isnan (r)) cond = ltype == rtype; else cond = l == r;out: swfdec_as_stack_pop (cx); SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), cond);}static voidswfdec_action_equals2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *rval, *lval; SwfdecAsValueType ltype, rtype; double l, r; gboolean cond; rval = swfdec_as_stack_peek (cx, 1); lval = swfdec_as_stack_peek (cx, 2); ltype = lval->type; rtype = rval->type; /* get objects compared */ if (ltype == SWFDEC_AS_TYPE_OBJECT && rtype == SWFDEC_AS_TYPE_OBJECT) { SwfdecAsObject *lo = SWFDEC_AS_VALUE_GET_OBJECT (lval); SwfdecAsObject *ro = SWFDEC_AS_VALUE_GET_OBJECT (rval); if (SWFDEC_IS_MOVIE (lo) && SWFDEC_IS_MOVIE (ro)) { /* do nothing */ } else if (SWFDEC_IS_MOVIE (lo)) { swfdec_as_value_to_primitive (rval); rtype = rval->type; if (rtype != SWFDEC_AS_TYPE_OBJECT) { cond = FALSE; goto out; } ro = SWFDEC_AS_VALUE_GET_OBJECT (rval); } else if (SWFDEC_IS_MOVIE (ro)) { swfdec_as_value_to_primitive (lval); ltype = lval->type; if (ltype != SWFDEC_AS_TYPE_OBJECT) { cond = FALSE; goto out; } lo = SWFDEC_AS_VALUE_GET_OBJECT (lval); } cond = lo == ro; goto out; } /* if one of the values is an object, call valueOf. * If it's still an object, return FALSE */ swfdec_as_value_to_primitive (lval); ltype = lval->type; if (ltype == SWFDEC_AS_TYPE_OBJECT) { cond = FALSE; goto out; } swfdec_as_value_to_primitive (rval); rtype = rval->type; if (rtype == SWFDEC_AS_TYPE_OBJECT) { cond = FALSE; goto out; } /* now we have a comparison without objects */ /* get rid of undefined and null */ cond = rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL; if (ltype == SWFDEC_AS_TYPE_UNDEFINED || ltype == SWFDEC_AS_TYPE_NULL) { goto out; } else if (cond) { cond = FALSE; goto out; } /* compare strings */ if (ltype == SWFDEC_AS_TYPE_STRING && rtype == SWFDEC_AS_TYPE_STRING) { /* FIXME: flash 5 case insensitive? */ cond = SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval); goto out; } /* else compare as numbers */ l = swfdec_as_value_to_number (cx, lval); r = swfdec_as_value_to_number (cx, rval); if (isnan (l) && isnan (r)) cond = ltype == rtype; else cond = l == r;out: swfdec_as_stack_pop (cx); SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), cond);}static voidswfdec_action_strict_equals (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *rval, *lval; gboolean cond; rval = swfdec_as_stack_peek (cx, 1); lval = swfdec_as_stack_peek (cx, 2); if (rval->type != lval->type) { cond = FALSE; } else { switch (rval->type) { case SWFDEC_AS_TYPE_UNDEFINED: case SWFDEC_AS_TYPE_NULL: cond = TRUE; break; case SWFDEC_AS_TYPE_BOOLEAN: cond = SWFDEC_AS_VALUE_GET_BOOLEAN (rval) == SWFDEC_AS_VALUE_GET_BOOLEAN (lval); break; case SWFDEC_AS_TYPE_NUMBER: { double l, r; r = SWFDEC_AS_VALUE_GET_NUMBER (rval); l = SWFDEC_AS_VALUE_GET_NUMBER (lval); cond = (l == r) || (isnan (l) && isnan (r)); } break; case SWFDEC_AS_TYPE_STRING: cond = SWFDEC_AS_VALUE_GET_STRING (rval) == SWFDEC_AS_VALUE_GET_STRING (lval); break; case SWFDEC_AS_TYPE_OBJECT: cond = SWFDEC_AS_VALUE_GET_OBJECT (rval) == SWFDEC_AS_VALUE_GET_OBJECT (lval); break; default: g_assert_not_reached (); cond = FALSE; } } swfdec_as_stack_pop (cx); SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), cond);}static voidswfdec_action_set_target (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ if (!memchr (data, 0, len)) { SWFDEC_ERROR ("SetTarget action does not specify a string"); return; } if (*data == '\0') { swfdec_as_frame_set_target (cx->frame, NULL); } else { SwfdecAsValue target; swfdec_as_context_eval (cx, NULL, (const char *) data, &target); if (!SWFDEC_AS_VALUE_IS_OBJECT (&target)) { SWFDEC_WARNING ("target is not an object"); return; } /* FIXME: allow non-movieclips as targets? */ swfdec_as_frame_set_target (cx->frame, SWFDEC_AS_VALUE_GET_OBJECT (&target)); }}static voidswfdec_action_set_target2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; val = swfdec_as_stack_peek (cx, 1); if (!SWFDEC_AS_VALUE_IS_OBJECT (val)) { SWFDEC_WARNING ("target is not an object"); } else { /* FIXME: allow non-movieclips as targets? */ swfdec_as_frame_set_target (cx->frame, SWFDEC_AS_VALUE_GET_OBJECT (val)); } swfdec_as_stack_pop (cx);}static voidswfdec_action_start_drag (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ guint n_args = 1; swfdec_as_stack_ensure_size (cx, 3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -