📄 swfdec_as_interpret.c
字号:
swfdec_action_store_register (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ if (len != 1) { SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len); return; } if (!swfdec_action_has_register (cx, *data)) { SWFDEC_ERROR ("Cannot store into register %u, not enough registers", (guint) *data); return; } cx->frame->registers[*data] = *swfdec_as_stack_peek (cx, 1);}static voidswfdec_action_modulo (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ double x, y; y = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 1)); x = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 2)); /* yay, we're portable! */ if (y == 0.0) { x = NAN; } else { errno = 0; x = fmod (x, y); if (errno != 0) { SWFDEC_FIXME ("errno set after fmod"); } } swfdec_as_stack_pop (cx); SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), x);}static voidswfdec_action_swap (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ swfdec_as_stack_swap (cx, 1, 2);}static voidswfdec_action_to_number (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 1)));}static voidswfdec_action_to_string (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_peek (cx, 1), swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1)));}static voidswfdec_action_type_of (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; const char *type; val = swfdec_as_stack_peek (cx, 1); switch (val->type) { case SWFDEC_AS_TYPE_NUMBER: type = SWFDEC_AS_STR_number; break; case SWFDEC_AS_TYPE_BOOLEAN: type = SWFDEC_AS_STR_boolean; break; case SWFDEC_AS_TYPE_STRING: type = SWFDEC_AS_STR_string; break; case SWFDEC_AS_TYPE_UNDEFINED: type = SWFDEC_AS_STR_undefined; break; case SWFDEC_AS_TYPE_NULL: type = SWFDEC_AS_STR_null; break; case SWFDEC_AS_TYPE_OBJECT: { SwfdecAsObject *obj = SWFDEC_AS_VALUE_GET_OBJECT (val); if (SWFDEC_IS_MOVIE (obj)) { type = SWFDEC_AS_STR_movieclip; } else if (SWFDEC_IS_AS_FUNCTION (obj)) { type = SWFDEC_AS_STR_function; } else { type = SWFDEC_AS_STR_object; } } break; default: g_assert_not_reached (); type = SWFDEC_AS_STR_EMPTY; break; } SWFDEC_AS_VALUE_SET_STRING (val, type);}static voidswfdec_action_get_time (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ GTimeVal tv; gulong diff; swfdec_as_context_get_time (cx, &tv); /* we assume here that swfdec_as_context_get_time always returns a tv > start_time */ diff = tv.tv_sec - cx->start_time.tv_sec; if (diff > G_MAXULONG / 1000 - 1) { SWFDEC_ERROR ("FIXME: time overflow"); } diff *= 1000; diff = diff + (tv.tv_usec - cx->start_time.tv_usec) / 1000; SWFDEC_AS_VALUE_SET_INT (swfdec_as_stack_push (cx), diff);}static voidswfdec_action_extends (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *superclass, *subclass, proto; SwfdecAsObject *prototype; SwfdecAsObject *super; superclass = swfdec_as_stack_peek (cx, 1); subclass = swfdec_as_stack_peek (cx, 2); if (!SWFDEC_AS_VALUE_IS_OBJECT (superclass) || !SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (superclass))) { SWFDEC_ERROR ("superclass is not a function"); goto fail; } if (!SWFDEC_AS_VALUE_IS_OBJECT (subclass)) { SWFDEC_ERROR ("subclass is not an object"); goto fail; } super = SWFDEC_AS_VALUE_GET_OBJECT (superclass); prototype = swfdec_as_object_new_empty (cx); if (prototype == NULL) return; swfdec_as_object_get_variable (super, SWFDEC_AS_STR_prototype, &proto); swfdec_as_object_set_variable (prototype, SWFDEC_AS_STR___proto__, &proto); swfdec_as_object_set_variable_and_flags (prototype, SWFDEC_AS_STR___constructor__, superclass, SWFDEC_AS_VARIABLE_HIDDEN); SWFDEC_AS_VALUE_SET_OBJECT (&proto, prototype); swfdec_as_object_set_variable (SWFDEC_AS_VALUE_GET_OBJECT (subclass), SWFDEC_AS_STR_prototype, &proto);fail: swfdec_as_stack_pop_n (cx, 2);}static gbooleanswfdec_action_do_enumerate (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer cxp){ SwfdecAsContext *cx = cxp; if (flags & SWFDEC_AS_VARIABLE_HIDDEN) return TRUE; swfdec_as_stack_ensure_free (cx, 1); SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (cx), variable); return TRUE;}static voidswfdec_action_enumerate (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; SwfdecAsObject *obj; val = swfdec_as_stack_peek (cx, 1); swfdec_as_interpret_eval (cx, NULL, val); if (!SWFDEC_AS_VALUE_IS_OBJECT (val)) { SWFDEC_ERROR ("Enumerate not pointing to an object"); SWFDEC_AS_VALUE_SET_NULL (val); return; } obj = SWFDEC_AS_VALUE_GET_OBJECT (val); SWFDEC_AS_VALUE_SET_NULL (val); swfdec_as_object_foreach (obj, swfdec_action_do_enumerate, cx);}static voidswfdec_action_enumerate2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; SwfdecAsObject *obj; val = swfdec_as_stack_peek (cx, 1); if (!SWFDEC_AS_VALUE_IS_OBJECT (val)) { SWFDEC_ERROR ("Enumerate2 called without an object"); SWFDEC_AS_VALUE_SET_NULL (val); return; } obj = SWFDEC_AS_VALUE_GET_OBJECT (val); SWFDEC_AS_VALUE_SET_NULL (val); swfdec_as_object_foreach (obj, swfdec_action_do_enumerate, cx);}static voidswfdec_action_logical (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val; gboolean l, r; l = swfdec_as_value_to_boolean (cx, swfdec_as_stack_peek (cx, 1)); val = swfdec_as_stack_peek (cx, 2); r = swfdec_as_value_to_boolean (cx, val); SWFDEC_AS_VALUE_SET_BOOLEAN (val, (action == 0x10) ? (l && r) : (l || r)); swfdec_as_stack_pop (cx);}static voidswfdec_action_char_to_ascii_5 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1); const char *s = swfdec_as_value_to_string (cx, val); char *ascii; ascii = g_convert (s, -1, "LATIN1", "UTF-8", NULL, NULL, NULL); if (ascii == NULL) { /* This can happen if a Flash 5 movie gets loaded into a Flash 7 movie */ SWFDEC_FIXME ("Someone threw unconvertible text %s at Flash <= 5", s); SWFDEC_AS_VALUE_SET_INT (val, 0); /* FIXME: what to return??? */ } else { SWFDEC_AS_VALUE_SET_INT (val, (guchar) ascii[0]); g_free (ascii); }}static voidswfdec_action_char_to_ascii (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1); const char *s = swfdec_as_value_to_string(cx, val); gunichar *uni; uni = g_utf8_to_ucs4_fast (s, -1, NULL); if (uni == NULL) { /* This should never happen, everything is valid UTF-8 in here */ g_warning ("conversion of character %s failed", s); SWFDEC_AS_VALUE_SET_INT (val, 0); } else { SWFDEC_AS_VALUE_SET_INT (val, uni[0]); g_free (uni); }}static voidswfdec_action_ascii_to_char (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ char *s; SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1); gunichar c = ((guint) swfdec_as_value_to_integer (cx, val)) % 65536; s = g_ucs4_to_utf8 (&c, 1, NULL, NULL, NULL); if (s == NULL) { g_warning ("conversion of character %u failed", (guint) c); SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY); } else { SWFDEC_AS_VALUE_SET_STRING (val, swfdec_as_context_get_string (cx, s)); g_free (s); }}static voidswfdec_action_ascii_to_char_5 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1); char s[2]; char *utf8; s[0] = ((guint) swfdec_as_value_to_integer (cx, val)) % 256; s[1] = 0; utf8 = g_convert (s, -1, "UTF-8", "LATIN1", NULL, NULL, NULL); if (utf8 == NULL) { g_warning ("conversion of character %u failed", (guint) s[0]); SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY); } else { SWFDEC_AS_VALUE_SET_STRING (val, swfdec_as_context_get_string (cx, utf8)); g_free (utf8); }}static voidswfdec_action_mb_ascii_to_char_5 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1); char s[3]; char *utf8; guint i; i = ((guint) swfdec_as_value_to_integer (cx, val)); if (i > 255) { s[0] = i / 256; s[1] = i % 256; s[2] = 0; } else { s[0] = i; s[1] = 0; } utf8 = g_convert (s, -1, "UTF-8", "LATIN1", NULL, NULL, NULL); if (utf8 == NULL) { g_warning ("conversion of character %u failed", i); SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY); } else { SWFDEC_AS_VALUE_SET_STRING (val, swfdec_as_context_get_string (cx, utf8)); g_free (utf8); }}static voidswfdec_action_with (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsObject *object; guint offset; if (len != 2) { SWFDEC_ERROR ("With action requires a length of 2, but got %u", len); swfdec_as_stack_pop (cx); return; } offset = data[0] | (data[1] << 8); object = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (cx, 1)); if (object == NULL) { SWFDEC_INFO ("With called without an object, skipping"); cx->frame->pc = (guint8 *) data + len + offset; } else { swfdec_as_with_new (object, data + len, offset); } swfdec_as_stack_pop (cx);}static voidswfdec_action_remove_sprite (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1); SwfdecAsObject *sprite; SwfdecMovie *movie; if (SWFDEC_AS_VALUE_IS_STRING (val)) { const char *name = SWFDEC_AS_VALUE_GET_STRING (val); swfdec_as_context_eval (cx, NULL, name, val); } if (SWFDEC_AS_VALUE_IS_OBJECT (val)) { sprite = SWFDEC_AS_VALUE_GET_OBJECT (val); } else { SWFDEC_FIXME ("unknown type in RemoveSprite"); goto fail; } if (!SWFDEC_IS_MOVIE (sprite)) { SWFDEC_FIXME ("cannot remove non movieclip objects"); goto fail; } movie = SWFDEC_MOVIE (sprite); if (swfdec_depth_classify (movie->depth) == SWFDEC_DEPTH_CLASS_DYNAMIC) { SWFDEC_LOG ("removing clip %s", movie->name); swfdec_movie_remove (movie); }fail: swfdec_as_stack_pop (cx);}static voidswfdec_action_clone_sprite (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){ SwfdecMovie *movie, *new_movie; SwfdecAsObject *obj; const char *new_name; int depth; depth = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 1)) - 16384; new_name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2)); if (SWFDEC_AS_VALUE_IS_STRING (swfdec_as_stack_peek (cx, 3))) { const char *name; name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 3)); swfdec_as_context_eval (cx, NULL, name, swfdec_as_stack_peek (cx, 3)); } obj = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (cx, 3)); if (!SWFDEC_IS_MOVIE(obj)) { SWFDEC_ERROR ("Object is not an SwfdecMovie object"); swfdec_as_stack_pop_n (cx, 3); return; } movie = SWFDEC_MOVIE(obj); new_movie = swfdec_movie_duplicate (movie, new_name, depth); if (new_movie) { SWFDEC_LOG ("duplicated %s as %s to depth %u", movie->name, new_movie->name, new_movie->depth); if (SWFDEC_IS_SPRITE_MOVIE (new_movie)) { g_queue_push_tail (SWFDEC_PLAYER (cx)->init_queue, new_movie); swfdec_movie_queue_script (new_movie, SWFDEC_EVENT_LOAD); swfdec_movie_run_construct (new_movie); } swfdec_movie_initialize (new_movie); } swfdec_as_stack_pop_n (cx, 3);}/*** PRINT FUNCTIONS ***/static char *swfdec_action_print_with (guint action, const guint8 *data, guint len){ if (len != 2) { SWFDEC_ERROR ("With action requires a length of 2, but got %u", len); return NULL; } return g_strdup_printf ("With %u", data[0] | (data[1] << 8));}static char *swfdec_action_print_store_register (guint action, const guint8 *data, guint len){ if (len != 1) { SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len); return NULL; } return g_strdup_printf ("StoreRegister %u", (guint) *data);}static char *swfdec_action_print_set_target (guint action, const guint8 *data, guint len){ if (!memchr (data, 0, len)) { SWFDEC_ERROR ("SetTarget action does not specify a string"); return NULL; } return g_strconcat ("SetTarget ", data, NULL);}static char *swfdec_action_print_d
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -