⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_as_interpret.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (swfdec_as_interpret_eval (cx, NULL, swfdec_as_stack_peek (cx, 1)) == SWFDEC_AS_STR_EMPTY) {    SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (cx, 1), cx->frame->target);  }  if (swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 3))) {    swfdec_as_stack_ensure_size (cx, 7);    n_args = 5;    /* yay for order */    swfdec_as_stack_swap (cx, 4, 7);    swfdec_as_stack_swap (cx, 5, 6);  }  if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (cx, 1))) {    swfdec_as_stack_pop_n (cx, n_args + 2);    return;  }  *swfdec_as_stack_peek (cx, 3) = *swfdec_as_stack_peek (cx, 2);  *swfdec_as_stack_peek (cx, 2) = *swfdec_as_stack_peek (cx, 1);  swfdec_as_object_get_variable (SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (cx, 2)),      SWFDEC_AS_STR_startDrag, swfdec_as_stack_peek (cx, 1));  swfdec_action_call (cx, n_args);  /* FIXME: the return value will still be written to this position */  swfdec_as_stack_pop (cx);}static voidswfdec_action_end_drag (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  if (SWFDEC_IS_PLAYER (cx)) {    swfdec_player_set_drag_movie (SWFDEC_PLAYER (cx), NULL, FALSE, NULL);  } else {    SWFDEC_WARNING ("can't end a drag on non-players");  }}static voidswfdec_action_stop_sounds (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  if (SWFDEC_IS_PLAYER (cx)) {    swfdec_player_stop_all_sounds (SWFDEC_PLAYER (cx));  }}static voidswfdec_action_new_object (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *constructor;  SwfdecAsFunction *fun;  guint n_args;  const char *name;  swfdec_as_stack_ensure_size (cx, 2);  constructor = swfdec_as_stack_peek (cx, 1);  name = swfdec_as_interpret_eval (cx, NULL, constructor);  n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 2));  n_args = MIN (swfdec_as_stack_get_size (cx) - 2, n_args);  if (!SWFDEC_AS_VALUE_IS_OBJECT (constructor) ||      !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (constructor))) {    SWFDEC_WARNING ("%s is not a constructor", name);    goto fail;  }  swfdec_as_stack_pop_n (cx, 2);  swfdec_as_object_create (fun, n_args, NULL);  return;fail:  swfdec_as_stack_pop_n (cx, n_args + 1);  SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 1));}static voidswfdec_action_new_method (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *constructor;  SwfdecAsFunction *fun;  guint n_args;  const char *name;  swfdec_as_stack_ensure_size (cx, 3);  name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));  constructor = swfdec_as_stack_peek (cx, 2);  n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 3));  n_args = MIN (swfdec_as_stack_get_size (cx) - 3, n_args);  if (name != SWFDEC_AS_STR_EMPTY) {    if (!SWFDEC_AS_VALUE_IS_OBJECT (constructor)) {      SWFDEC_WARNING ("NewMethod called without an object to get variable %s from", name);      goto fail;    }    swfdec_as_object_get_variable (SWFDEC_AS_VALUE_GET_OBJECT (constructor),	name, constructor);  }  if (!SWFDEC_AS_VALUE_IS_OBJECT (constructor) ||      !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (constructor))) {    SWFDEC_WARNING ("%s is not a constructor", name);    goto fail;  }  swfdec_as_stack_pop_n (cx, 3);  swfdec_as_object_create (fun, n_args, NULL);  return;fail:  swfdec_as_stack_pop_n (cx, n_args + 2);  SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 1));}static voidswfdec_action_init_object (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsObject *object;  guint i, n_args, size;  n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 1));  swfdec_as_stack_pop (cx);  if (n_args * 2 > swfdec_as_stack_get_size (cx)) {    size = swfdec_as_stack_get_size (cx);    SWFDEC_FIXME ("InitObject action with too small stack, help!");    n_args = size / 2;    size &= 1;  } else {    size = 0;  }  object = swfdec_as_object_new (cx);  if (object == NULL)    return;  for (i = 0; i < n_args; i++) {    const char *s = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2));    swfdec_as_object_set_variable (object, s, swfdec_as_stack_peek (cx, 1));    swfdec_as_stack_pop_n (cx, 2);  }  swfdec_as_stack_pop_n (cx, size);  SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_push (cx), object);}static voidswfdec_action_init_array (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  int i, n;  SwfdecAsObject *array;  swfdec_as_stack_ensure_size (cx, 1);  n = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 1));  swfdec_as_stack_pop (cx);  array = swfdec_as_array_new (cx);  if (array == NULL)    return;  /* NB: we can't increase the stack here, as the number can easily be MAXINT */  for (i = 0; i < n && swfdec_as_stack_get_size (cx) > 0; i++) {    swfdec_as_stack_ensure_size (cx, 1);    swfdec_as_array_push (SWFDEC_AS_ARRAY (array), swfdec_as_stack_pop (cx));  }  if (i != n) {    SwfdecAsValue val;    SWFDEC_AS_VALUE_SET_INT (&val, i);    swfdec_as_object_set_variable (array, SWFDEC_AS_STR_length, &val);  }  SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_push (cx), array);}static voidswfdec_action_define_function (SwfdecAsContext *cx, guint action,    const guint8 *data, guint len){  char *function_name;  const char *name = NULL;  guint i, n_args, size, n_registers;  SwfdecBuffer *buffer;  SwfdecBits bits;  SwfdecAsFunction *fun;  SwfdecAsFrame *frame;  SwfdecScript *script;  guint flags = 0;  SwfdecScriptArgument *args;  gboolean v2 = (action == 0x8e);  frame = cx->frame;  swfdec_bits_init_data (&bits, data, len);  function_name = swfdec_bits_get_string_with_version (&bits, cx->version);  if (function_name == NULL) {    SWFDEC_ERROR ("could not parse function name");    return;  }  n_args = swfdec_bits_get_u16 (&bits);  if (v2) {    n_registers = swfdec_bits_get_u8 (&bits);    if (n_registers == 0)      n_registers = 4;    flags = swfdec_bits_get_u16 (&bits);  } else {    n_registers = 5;  }  if (n_args) {    args = g_new0 (SwfdecScriptArgument, n_args);    for (i = 0; i < n_args && swfdec_bits_left (&bits); i++) {      if (v2) {	args[i].preload = swfdec_bits_get_u8 (&bits);	if (args[i].preload && args[i].preload >= n_registers) {	  SWFDEC_ERROR ("argument %u cannot be preloaded into register %u out of %u", 	      i, args[i].preload, n_registers);	  /* FIXME: figure out correct error handling here */	  args[i].preload = 0;	}      }      args[i].name = swfdec_bits_get_string_with_version (&bits, cx->version);      if (args[i].name == NULL || args[i].name == '\0') {	SWFDEC_ERROR ("empty argument name not allowed");	g_free (args);	return;      }      /* FIXME: check duplicate arguments */    }  } else {    args = NULL;  }  size = swfdec_bits_get_u16 (&bits);  /* check the script can be created */  if (frame->script->buffer->data + frame->script->buffer->length < frame->pc + 3 + len + size) {    SWFDEC_ERROR ("size of function is too big");    g_free (args);    g_free (function_name);    return;  }  /* create the script */  buffer = swfdec_buffer_new_subbuffer (frame->script->buffer,       frame->pc + 3 + len - frame->script->buffer->data, size);  swfdec_bits_init (&bits, buffer);  if (*function_name) {    name = function_name;  } else if (swfdec_as_stack_get_size (cx) > 0) {    /* This is kind of a hack that uses a feature of the Adobe compiler:     * foo = function () {} is compiled as these actions:     * Push "foo", DefineFunction, SetVariable/SetMember     * With this knowledge we can inspect the topmost stack member, since     * it will contain the name this function will soon be assigned to.     */    if (SWFDEC_AS_VALUE_IS_STRING (swfdec_as_stack_peek (cx, 1)))      name = SWFDEC_AS_VALUE_GET_STRING (swfdec_as_stack_peek (cx, 1));  }  if (name == NULL)    name = "unnamed_function";  script = swfdec_script_new_from_bits (&bits, name, cx->version);  swfdec_buffer_unref (buffer);  if (script == NULL) {    SWFDEC_ERROR ("failed to create script");    g_free (args);    g_free (function_name);    return;  }  if (frame->constant_pool_buffer)    script->constant_pool = swfdec_buffer_ref (frame->constant_pool_buffer);  script->flags = flags;  script->n_registers = n_registers;  script->n_arguments = n_args;  script->arguments = args;  /* see function-scope tests */  if (cx->version > 5) {    /* FIXME: or original target? */    fun = swfdec_as_script_function_new (frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame), frame->target, script);  } else {    SwfdecAsScope *scope = frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame);    while (scope->next)      scope = scope->next;    fun = swfdec_as_script_function_new (scope, frame->target, script);  }  if (fun == NULL)    return;  /* attach the function */  if (*function_name == '\0') {    swfdec_as_stack_ensure_free (cx, 1);    SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_push (cx), SWFDEC_AS_OBJECT (fun));  } else {    SwfdecAsValue funval;    /* FIXME: really varobj? Not eval or sth like that? */    name = swfdec_as_context_get_string (cx, function_name);    SWFDEC_AS_VALUE_SET_OBJECT (&funval, SWFDEC_AS_OBJECT (fun));    swfdec_as_object_set_variable (frame->target, name, &funval);  }  /* update current context */  frame->pc += 3 + len + size;  g_free (function_name);}static voidswfdec_action_bitwise (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  int a, b;  a = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 1));  b = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 2));  switch (action) {    case 0x60:      a = (int) (a & b);      break;    case 0x61:      a = (int) (a | b);      break;    case 0x62:      a = (int) (a ^ b);      break;    default:      g_assert_not_reached ();      break;  }  swfdec_as_stack_pop (cx);  SWFDEC_AS_VALUE_SET_INT (swfdec_as_stack_peek (cx, 1), a);}static voidswfdec_action_shift (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  int amount, value;  amount = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 1));  amount &= 31;  value = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 2));  switch (action) {    case 0x63:      value = value << amount;      break;    case 0x64:      value = ((gint) value) >> amount;      break;    case 0x65:      value = ((guint) value) >> amount;      break;    default:      g_assert_not_reached ();  }  swfdec_as_stack_pop (cx);  SWFDEC_AS_VALUE_SET_INT (swfdec_as_stack_peek (cx, 1), value);}static voidswfdec_action_to_integer (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val = swfdec_as_stack_peek (cx, 1);  SWFDEC_AS_VALUE_SET_INT (val, swfdec_as_value_to_integer (cx, val));}static voidswfdec_action_target_path (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val;  SwfdecMovie *movie;  char *s;  val = swfdec_as_stack_peek (cx, 1);  if (!SWFDEC_AS_VALUE_IS_OBJECT (val) ||      !SWFDEC_IS_MOVIE (movie = (SwfdecMovie *) SWFDEC_AS_VALUE_GET_OBJECT (val))) {    SWFDEC_FIXME ("What's the TargetPath for non-movies?");    SWFDEC_AS_VALUE_SET_UNDEFINED (val);    return;  }  s = swfdec_movie_get_path (movie);  SWFDEC_AS_VALUE_SET_STRING (val, swfdec_as_context_give_string (cx, s));}static voidswfdec_action_define_local (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsObject *target;  const char *name;  name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2));  if (cx->frame->is_local) {    target = SWFDEC_AS_OBJECT (cx->frame);  } else {    target = cx->frame->target;  }  swfdec_as_object_set_variable (target, name,      swfdec_as_stack_peek (cx, 1));  swfdec_as_stack_pop_n (cx, 2);}static voidswfdec_action_define_local2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue val = { 0, };  SwfdecAsObject *target;  const char *name;  name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));  if (cx->frame->is_local) {    target = SWFDEC_AS_OBJECT (cx->frame);  } else {    target = cx->frame->target;  }  swfdec_as_object_set_variable (target, name, &val);  swfdec_as_stack_pop (cx);}static voidswfdec_action_return (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  swfdec_as_frame_return (cx->frame, swfdec_as_stack_pop (cx));}static voidswfdec_action_delete (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val;  const char *name;  gboolean success = FALSE;    name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));  val = swfdec_as_stack_peek (cx, 2);  if (SWFDEC_AS_VALUE_IS_OBJECT (val)) {    success = swfdec_as_object_delete_variable (	SWFDEC_AS_VALUE_GET_OBJECT (val), name) == SWFDEC_AS_DELETE_DELETED;  }  SWFDEC_AS_VALUE_SET_BOOLEAN (val, success);  swfdec_as_stack_pop_n (cx, 1);}static voidswfdec_action_delete2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val;  const char *name;  gboolean success = FALSE;    val = swfdec_as_stack_peek (cx, 1);  name = swfdec_as_value_to_string (cx, val);  success = swfdec_as_frame_delete_variable (cx->frame, name) == SWFDEC_AS_DELETE_DELETED;  SWFDEC_AS_VALUE_SET_BOOLEAN (val, success);}static void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -