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

📄 swfdec_as_interpret.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 5 页
字号:
swfdec_as_interpret_eval (SwfdecAsContext *cx, SwfdecAsObject *obj,     SwfdecAsValue *val){  if (SWFDEC_AS_VALUE_IS_STRING (val)) {    const char *s = SWFDEC_AS_VALUE_GET_STRING (val);    if (s != SWFDEC_AS_STR_EMPTY) {      swfdec_as_context_eval (cx, obj, s, val);      return s;    }  }   if (obj != NULL)    SWFDEC_AS_VALUE_SET_OBJECT (val, obj);  else    SWFDEC_AS_VALUE_SET_UNDEFINED (val);  return SWFDEC_AS_STR_EMPTY;}/* FIXME: this sucks */extern struct {  gboolean needs_movie;  const char * name; /* GC'd */  void (* get) (SwfdecMovie *movie, SwfdecAsValue *ret);  void (* set) (SwfdecMovie *movie, const SwfdecAsValue *val);} swfdec_movieclip_props[];static voidswfdec_action_get_property (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val;  SwfdecAsObject *obj;  guint id;  id = swfdec_as_value_to_integer (cx, swfdec_as_stack_pop (cx));  if (id > (cx->version > 4 ? 21 : 18)) {    SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id);    goto out;  }  val = swfdec_as_stack_peek (cx, 1);  swfdec_as_interpret_eval (cx, NULL, val);  if (SWFDEC_AS_VALUE_IS_UNDEFINED (val)) {    obj = cx->frame->target;  } else if (SWFDEC_AS_VALUE_IS_OBJECT (val)) {    obj = SWFDEC_AS_VALUE_GET_OBJECT (val);  } else {    SWFDEC_WARNING ("not an object, can't GetProperty");    goto out;  }  swfdec_as_object_get_variable (obj, swfdec_movieclip_props[id].name,      swfdec_as_stack_peek (cx, 1));  return;out:  SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 1));}static voidswfdec_action_set_property (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val;  SwfdecAsObject *obj;  guint id;  id = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 2));  if (id > (cx->version > 4 ? 21 : 18)) {    SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id);    goto out;  }  val = swfdec_as_stack_peek (cx, 3);  swfdec_as_interpret_eval (cx, NULL, val);  if (SWFDEC_AS_VALUE_IS_UNDEFINED (val)) {    obj = cx->frame->target;  } else if (SWFDEC_AS_VALUE_IS_OBJECT (val)) {    obj = SWFDEC_AS_VALUE_GET_OBJECT (val);  } else {    SWFDEC_WARNING ("not an object, can't get SetProperty");    goto out;  }  swfdec_as_object_set_variable (obj, swfdec_movieclip_props[id].name,      swfdec_as_stack_peek (cx, 1));out:  swfdec_as_stack_pop_n (cx, 3);}static voidswfdec_action_get_member (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsObject *object = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (cx, 2));  if (object) {    const char *name;    name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));    swfdec_as_object_get_variable (object, name, swfdec_as_stack_peek (cx, 2));#ifdef SWFDEC_WARN_MISSING_PROPERTIES    if (SWFDEC_AS_VALUE_IS_UNDEFINED (swfdec_as_stack_peek (cx, 2))) {	SWFDEC_WARNING ("no variable named %s:%s", G_OBJECT_TYPE_NAME (object), name);    }#endif  } else {    SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 2));  }  swfdec_as_stack_pop (cx);}static voidswfdec_action_set_member (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  if (SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (cx, 3))) {    const char *name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2));    swfdec_as_object_set_variable (SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (cx, 3)),	name, swfdec_as_stack_peek (cx, 1));  }  swfdec_as_stack_pop_n (cx, 3);}static voidswfdec_action_trace (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *val;  const char *s;  val = swfdec_as_stack_peek (cx, 1);  if (val->type == SWFDEC_AS_TYPE_UNDEFINED) {    s = SWFDEC_AS_STR_undefined;  } else if (val->type == SWFDEC_AS_TYPE_OBJECT &&      SWFDEC_IS_AS_STRING (swfdec_as_value_to_object (cx, val))) {    s = SWFDEC_AS_STRING (swfdec_as_value_to_object (cx, val))->string;  } else {    s = swfdec_as_value_to_string (cx, val);  }  swfdec_as_stack_pop (cx);  g_signal_emit_by_name (cx, "trace", s);}/* stack looks like this: [ function, this, arg1, arg2, ... ] *//* stack must be at least 2 elements big */static gbooleanswfdec_action_call (SwfdecAsContext *cx, guint n_args){  SwfdecAsFunction *fun;  SwfdecAsObject *thisp;  if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (cx, 1)))    goto error;  fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (cx, 1));  if (!SWFDEC_IS_AS_FUNCTION (fun))    goto error;  if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (cx, 2))) {    thisp = NULL;  } else {    thisp = SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (cx, 2));  }  swfdec_as_stack_pop_n (cx, 2);  /* sanitize argument count */  if (n_args >= swfdec_as_stack_get_size (cx))    n_args = swfdec_as_stack_get_size (cx);  swfdec_as_function_call (fun, thisp, n_args, NULL, NULL);  if (SWFDEC_IS_AS_SUPER (fun)) {    SWFDEC_LOG ("replacing super object on frame");    swfdec_as_super_replace (SWFDEC_AS_SUPER (fun), NULL);  }  return TRUE;error:  n_args += 2;  if (n_args > swfdec_as_stack_get_size (cx))    n_args = swfdec_as_stack_get_size (cx);  swfdec_as_stack_pop_n (cx, n_args);  SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_push (cx));  return FALSE;}static voidswfdec_action_call_function (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsFrame *frame = cx->frame;  SwfdecAsObject *obj;  guint n_args;  const char *name;  SwfdecAsValue *fun, *thisp;    swfdec_as_stack_ensure_size (cx, 2);  n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 2));  name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));  thisp = swfdec_as_stack_peek (cx, 2);  fun = swfdec_as_stack_peek (cx, 1);  obj = swfdec_as_frame_find_variable (frame, name);  if (obj) {    swfdec_as_object_get_variable (obj, name, fun);    SWFDEC_AS_VALUE_SET_OBJECT (thisp, obj);  } else {    SWFDEC_AS_VALUE_SET_NULL (thisp);    SWFDEC_AS_VALUE_SET_UNDEFINED (fun);  }  if (!swfdec_action_call (cx, n_args)) {    SWFDEC_ERROR ("no function named %s", name);  }}static voidswfdec_action_call_method (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsFrame *frame = cx->frame;  SwfdecAsValue *val;  SwfdecAsObject *obj;  guint n_args;  const char *name = NULL;    swfdec_as_stack_ensure_size (cx, 3);  obj = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (cx, 2));  n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx, 3));  val = swfdec_as_stack_peek (cx, 1);  /* FIXME: this is a hack for constructors calling super - is this correct? */  if (SWFDEC_AS_VALUE_IS_UNDEFINED (val)) {    SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY);  }  if (obj) {    if (SWFDEC_AS_VALUE_IS_STRING (val) && 	SWFDEC_AS_VALUE_GET_STRING (val) == SWFDEC_AS_STR_EMPTY) {      SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 3));      SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (cx, 2), obj);    } else {      SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (cx, 3), obj);      name = swfdec_as_value_to_string (cx, val);      swfdec_as_object_get_variable (obj, name, swfdec_as_stack_peek (cx, 2));    }  } else {    if (SWFDEC_AS_VALUE_IS_STRING (val))      name = SWFDEC_AS_VALUE_GET_STRING (val);    SWFDEC_AS_VALUE_SET_NULL (swfdec_as_stack_peek (cx, 3));    SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 2));  }  swfdec_as_stack_pop (cx);  if (swfdec_action_call (cx, n_args)) {    /* setup super to point to the right prototype */    frame = cx->frame;    if (SWFDEC_IS_AS_SUPER (obj)) {      swfdec_as_super_replace (SWFDEC_AS_SUPER (obj), name);    } else if (frame->super) {      SwfdecAsSuper *super = SWFDEC_AS_SUPER (frame->super);      if (name && 	  cx->version > 6 && 	  swfdec_as_object_get_variable_and_flags (frame->thisp, 	    name, NULL, NULL, &super->object) && 	  super->object == frame->thisp) {	super->object = super->object->prototype;      }    }  } else {    SWFDEC_ERROR ("no function named %s on object %s", name ? name : "unknown", obj ? G_OBJECT_TYPE_NAME(obj) : "unknown");  }}static voidswfdec_action_pop (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  swfdec_as_stack_pop (cx);}static voidswfdec_action_binary (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  double l, r;  r = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 1));  l = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 2));  switch (action) {    case SWFDEC_AS_ACTION_ADD:      l = l + r;      break;    case SWFDEC_AS_ACTION_SUBTRACT:      l = l - r;      break;    case SWFDEC_AS_ACTION_MULTIPLY:      l = l * r;      break;    case SWFDEC_AS_ACTION_DIVIDE:      if (cx->version < 5) {	if (r == 0) {	  SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_peek (cx, 1), SWFDEC_AS_STR__ERROR_);	  return;	}      }      if (r == 0) {	if (l > 0)	  l = INFINITY;	else if (l < 0)	  l = -INFINITY;	else	  l = NAN;      } else {	l = l / r;      }      break;    default:      g_assert_not_reached ();      break;  }  swfdec_as_stack_pop (cx);  SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), l);}static voidswfdec_action_add2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *rval, *lval, rtmp, ltmp;  rval = swfdec_as_stack_peek (cx, 1);  lval = swfdec_as_stack_peek (cx, 2);  rtmp = *rval;  ltmp = *lval;  swfdec_as_value_to_primitive (&rtmp);  if (!SWFDEC_AS_VALUE_IS_OBJECT (&rtmp) || SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (&rtmp)))    rval = &rtmp;  swfdec_as_value_to_primitive (&ltmp);  if (!SWFDEC_AS_VALUE_IS_OBJECT (&ltmp) || SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (&ltmp)))    lval = &ltmp;  if (SWFDEC_AS_VALUE_IS_STRING (lval) || SWFDEC_AS_VALUE_IS_STRING (rval)) {    const char *lstr, *rstr;    lstr = swfdec_as_value_to_string (cx, lval);    rstr = swfdec_as_value_to_string (cx, rval);    lstr = swfdec_as_str_concat (cx, lstr, rstr);    swfdec_as_stack_pop (cx);    SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_peek (cx, 1), lstr);  } else {    double d, d2;    d = swfdec_as_value_to_number (cx, lval);    d2 = swfdec_as_value_to_number (cx, rval);    d += d2;    swfdec_as_stack_pop (cx);    SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), d);  }}static voidswfdec_action_new_comparison (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SwfdecAsValue *lval, *rval;  double l, r;  rval = swfdec_as_stack_peek (cx, 1);  lval = swfdec_as_stack_peek (cx, 2);  /* swap if we do a greater comparison */  if (action == SWFDEC_AS_ACTION_GREATER) {    SwfdecAsValue *tmp = lval;    lval = rval;    rval = tmp;  }  /* comparison with object is always false */  swfdec_as_value_to_primitive (lval);  if (SWFDEC_AS_VALUE_IS_OBJECT (lval) &&      !SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (lval))) {    swfdec_as_stack_pop (cx);    SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), FALSE);    return;  }  /* same for the rval */  swfdec_as_value_to_primitive (rval);  if (SWFDEC_AS_VALUE_IS_OBJECT (rval) &&      !SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (rval))) {    swfdec_as_stack_pop (cx);    SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), FALSE);    return;  }  /* movieclips are not objects, but they evaluate to NaN, so we can handle them here */  if (SWFDEC_AS_VALUE_IS_OBJECT (rval) ||      SWFDEC_AS_VALUE_IS_OBJECT (lval)) {    swfdec_as_stack_pop (cx);    SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 1));    return;  }  /* if both are strings, compare strings */  if (SWFDEC_AS_VALUE_IS_STRING (rval) &&      SWFDEC_AS_VALUE_IS_STRING (lval)) {    const char *ls = SWFDEC_AS_VALUE_GET_STRING (lval);    const char *rs = SWFDEC_AS_VALUE_GET_STRING (rval);    int cmp;    if (ls == SWFDEC_AS_STR_EMPTY) {      cmp = rs == SWFDEC_AS_STR_EMPTY ? 0 : 1;    } else if (rs == SWFDEC_AS_STR_EMPTY) {      cmp = -1;    } else {      cmp = strcmp (ls, rs);    }    swfdec_as_stack_pop (cx);    SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), cmp < 0);    return;  }  /* convert to numbers and compare those */  l = swfdec_as_value_to_number (cx, lval);  r = swfdec_as_value_to_number (cx, rval);  swfdec_as_stack_pop (cx);  /* NaN results in undefined */  if (isnan (l) || isnan (r)) {    SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (cx, 1));    return;  }  SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1), l < r);}static voidswfdec_action_not_4 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  double d;  d = swfdec_as_value_to_number (cx, swfdec_as_stack_peek (cx, 1));  SWFDEC_AS_VALUE_SET_NUMBER (swfdec_as_stack_peek (cx, 1), d == 0 ? 1 : 0);}static voidswfdec_action_not_5 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  SWFDEC_AS_VALUE_SET_BOOLEAN (swfdec_as_stack_peek (cx, 1),       !swfdec_as_value_to_boolean (cx, swfdec_as_stack_peek (cx, 1)));}static voidswfdec_action_jump (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  if (len != 2) {    SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);    return;  }  cx->frame->pc += 5 + GINT16_FROM_LE (*((gint16*) data)); }static voidswfdec_action_if (SwfdecAsContext *cx, guint action, const guint8 *data, guint len){  if (len != 2) {    SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);    return;  }  if (swfdec_as_value_to_boolean (cx, swfdec_as_stack_peek (cx, 1)))    cx->frame->pc += 5 + GINT16_FROM_LE (*((gint16*) data));   swfdec_as_stack_pop (cx);}

⌨️ 快捷键说明

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