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

📄 swfdec_as_context.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 3 页
字号:
      if (pc + 2 >= endpc) {	SWFDEC_ERROR ("action %u length value out of range", action);	goto error;      }      data = pc + 3;      len = pc[1] | pc[2] << 8;      if (data + len > endpc) {	SWFDEC_ERROR ("action %u length %u out of range", action, len);	goto error;      }      nextpc = pc + 3 + len;    } else {      data = NULL;      len = 0;      nextpc = pc + 1;    }    /* check action is valid */    exec = spec->exec[version];    if (!exec) {      guint real_version;      for (real_version = version + 1; !exec && 	  real_version <= SWFDEC_AS_MAX_SCRIPT_VERSION - SWFDEC_AS_MIN_SCRIPT_VERSION; 	  real_version++) {	exec = spec->exec[real_version];      }      if (!exec) {	SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, skipping it", action,	    action, spec->name ? spec->name : "Unknown", script->version);	frame->pc = pc = nextpc;	check_scope = TRUE;	continue;      }      SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, using version %u instead", 	  action, action, spec->name ? spec->name : "Unknown", script->version, 	  script->version + real_version - version);    }    if (spec->remove > 0) {      if (spec->add > spec->remove)	swfdec_as_stack_ensure_free (context, spec->add - spec->remove);      swfdec_as_stack_ensure_size (context, spec->remove);    } else {      if (spec->add > 0)	swfdec_as_stack_ensure_free (context, spec->add);    }    if (context->state > SWFDEC_AS_CONTEXT_RUNNING) {      SWFDEC_WARNING ("context not running anymore, aborting");      goto error;    }#ifndef G_DISABLE_ASSERT    check = (spec->add >= 0 && spec->remove >= 0) ? context->cur + spec->add - spec->remove : NULL;#endif    /* execute action */    exec (context, action, data, len);    /* adapt the pc if the action did not, otherwise, leave it alone */    /* FIXME: do this via flag? */    if (frame->pc == pc) {      frame->pc = pc = nextpc;      check_scope = TRUE;    } else {      pc = frame->pc;      check_scope = FALSE;    }    if (frame == context->frame) {#ifndef G_DISABLE_ASSERT      if (check != NULL && check != context->cur) {	g_error ("action %s was supposed to change the stack by %d (+%d -%d), but it changed by %td",	    spec->name, spec->add - spec->remove, spec->add, spec->remove,	    context->cur - check + spec->add - spec->remove);      }#endif    } else {      /* someone called/returned from a function, reread variables */      goto start;    }  }error:  while (context->frame != context->last_frame)    swfdec_as_frame_return (context->frame, NULL);out:  context->last_frame = last_frame;  return;}/*** EVAL ***/static char *swfdec_as_slash_to_dot (const char *slash_str){  const char *cur = slash_str;  GString *str = g_string_new ("");  if (*cur == '/') {    g_string_append (str, "_root");  } else {    goto start;  }  while (cur && *cur == '/') {    cur++;start:    if (str->len > 0)      g_string_append_c (str, '.');    if (cur[0] == '.' && cur[1] == '.') {      g_string_append (str, "_parent");      cur += 2;    } else {      char *slash = strchr (cur, '/');      if (slash) {	g_string_append_len (str, cur, slash - cur);	cur = slash;      } else {	g_string_append (str, cur);	cur = NULL;      }    }    /* cur should now point to the slash */  }  if (cur) {    if (*cur != '\0')      goto fail;  }  SWFDEC_DEBUG ("parsed slash-notated string \"%s\" into dot notation \"%s\"",      slash_str, str->str);  return g_string_free (str, FALSE);fail:  SWFDEC_WARNING ("failed to parse slash-notated string \"%s\" into dot notation", slash_str);  g_string_free (str, TRUE);  return NULL;}static voidswfdec_as_context_eval_get_property (SwfdecAsContext *cx,     SwfdecAsObject *obj, const char *name, SwfdecAsValue *ret){  if (obj) {    swfdec_as_object_get_variable (obj, name, ret);  } else {    if (cx->frame) {      obj = swfdec_as_frame_find_variable (cx->frame, name);      if (obj) {	swfdec_as_object_get_variable (obj, name, ret);	return;      }    } else {      SWFDEC_WARNING ("eval called without a frame");      swfdec_as_object_get_variable (cx->global, name, ret);    }    SWFDEC_AS_VALUE_SET_UNDEFINED (ret);  }}static voidswfdec_as_context_eval_set_property (SwfdecAsContext *cx,     SwfdecAsObject *obj, const char *name, const SwfdecAsValue *ret){  if (obj == NULL) {    if (cx->frame == NULL) {      SWFDEC_ERROR ("no frame in eval_set?");      return;    }    obj = swfdec_as_frame_find_variable (cx->frame, name);    if (obj == NULL || obj == cx->global)      obj = cx->frame->target;  }  swfdec_as_object_set_variable (obj, name, ret);}static voidswfdec_as_context_eval_internal (SwfdecAsContext *cx, SwfdecAsObject *obj, const char *str,        SwfdecAsValue *val, gboolean set){  SwfdecAsValue cur;  char **varlist;  guint i;  SWFDEC_LOG ("eval called with \"%s\" on %p", str, obj);  if (strchr (str, '/')) {    char *work = swfdec_as_slash_to_dot (str);    if (!work) {      SWFDEC_AS_VALUE_SET_UNDEFINED (val);      return;    }    varlist = g_strsplit (work, ".", -1);    g_free (work);  } else {    varlist = g_strsplit (str, ".", -1);  }  for (i = 0; varlist[i] != NULL; i++) {    const char *dot = swfdec_as_context_get_string (cx, varlist[i]);    if (varlist[i+1] != NULL) {      swfdec_as_context_eval_get_property (cx, obj, dot, &cur);      if (!SWFDEC_AS_VALUE_IS_OBJECT (&cur)) {	SWFDEC_AS_VALUE_SET_UNDEFINED (&cur);	break;      }      obj = SWFDEC_AS_VALUE_GET_OBJECT (&cur);    } else {      if (set) {	swfdec_as_context_eval_set_property (cx, obj, dot, val);      } else {	swfdec_as_context_eval_get_property (cx, obj, dot, &cur);      }      goto finish;    }  }  if (obj == NULL) {    if (cx->frame)      obj = cx->frame->target;    else      obj = cx->global;  }  g_assert (obj != NULL);  SWFDEC_AS_VALUE_SET_OBJECT (&cur, obj);finish:  g_strfreev (varlist);  *val = cur;}/** * swfdec_as_context_eval: * @context: a #SwfdecAsContext * @obj: #SwfdecAsObject to use as source for evaluating or NULL for the  *       current frame's scope * @str: The string to evaluate * @val: location for the return value * * This function works like the Actionscript eval function used on @obj. * It handles both slash-style and dot-style notation. If an error occured * during evaluation, the return value will be the undefined value. **/voidswfdec_as_context_eval (SwfdecAsContext *context, SwfdecAsObject *obj, const char *str,     SwfdecAsValue *val){  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));  g_return_if_fail (obj == NULL || SWFDEC_IS_AS_OBJECT (obj));  g_return_if_fail (str != NULL);  g_return_if_fail (val != NULL);  swfdec_as_context_eval_internal (context, obj, str, val, FALSE);}/** * swfdec_as_context_eval_set: * @context: a #SwfdecAsContext * @obj: #SwfdecAsObject to use as source for evaluating or NULL for the  *       default object. * @str: The string to evaluate * @val: the value to set the variable to * * Sets the variable referenced by @str to @val. If @str does not reference  * a valid property, nothing happens. **/voidswfdec_as_context_eval_set (SwfdecAsContext *context, SwfdecAsObject *obj, const char *str,    const SwfdecAsValue *val){  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));  g_return_if_fail (obj == NULL || SWFDEC_IS_AS_OBJECT (obj));  g_return_if_fail (str != NULL);  g_return_if_fail (val != NULL);  swfdec_as_context_eval_internal (context, obj, str, (SwfdecAsValue *) val, TRUE);}/*** AS CODE ***/static voidswfdec_as_context_ASSetPropFlags_set_one_flag (SwfdecAsObject *object,    const char *s, guint *flags){  swfdec_as_object_unset_variable_flags (object, s, flags[1]);  swfdec_as_object_set_variable_flags (object, s, flags[0]);}static gbooleanswfdec_as_context_ASSetPropFlags_foreach (SwfdecAsObject *object,    const char *s, SwfdecAsValue *val, guint cur_flags, gpointer data){  guint *flags = data;  /* shortcut if the flags already match */  if (cur_flags == ((cur_flags &~ flags[1]) | flags[0]))    return TRUE;  swfdec_as_context_ASSetPropFlags_set_one_flag (object, s, flags);  return TRUE;}static voidswfdec_as_context_ASSetPropFlags (SwfdecAsContext *cx, SwfdecAsObject *object,     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){  guint flags[2]; /* flags and mask - array so we can pass it as data pointer */  SwfdecAsObject *obj;  if (cx->version < 6) {    SWFDEC_FIXME ("ASSetPropFlags needs some limitations for Flash 5");  }  if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]))    return;  obj = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]);  flags[0] = swfdec_as_value_to_integer (cx, &argv[2]);  flags[1] = (argc > 3) ? swfdec_as_value_to_integer (cx, &argv[3]) : 0;  if (flags[0] == 0 && flags[1] == 0) {    // we should add autosizing length attribute here    SWFDEC_FIXME ("ASSetPropFlags to set special length attribute not implemented");    return;  }  if (SWFDEC_AS_VALUE_IS_NULL (&argv[1])) {    swfdec_as_object_foreach (obj, swfdec_as_context_ASSetPropFlags_foreach, flags);  } else {    char **split =      g_strsplit (swfdec_as_value_to_string (cx, &argv[1]), ",", -1);    guint i;    for (i = 0; split[i]; i++) {      swfdec_as_context_ASSetPropFlags_set_one_flag (obj, 	  swfdec_as_context_get_string (cx, split[i]), flags);    }    g_strfreev (split);   }}static voidswfdec_as_context_isFinite (SwfdecAsContext *cx, SwfdecAsObject *object,     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){  double d = swfdec_as_value_to_number (cx, &argv[0]);  SWFDEC_AS_VALUE_SET_BOOLEAN (retval, isfinite (d) ? TRUE : FALSE);}static voidswfdec_as_context_isNaN (SwfdecAsContext *cx, SwfdecAsObject *object,     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){  double d = swfdec_as_value_to_number (cx, &argv[0]);  SWFDEC_AS_VALUE_SET_BOOLEAN (retval, isnan (d) ? TRUE : FALSE);}static voidswfdec_as_context_parseInt (SwfdecAsContext *cx, SwfdecAsObject *object,     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval){  int i = swfdec_as_value_to_integer (cx, &argv[0]);  SWFDEC_AS_VALUE_SET_INT (retval, i);}static voidswfdec_as_context_init_global (SwfdecAsContext *context, guint version){  SwfdecAsValue val;  swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_ASSetPropFlags, 0,       swfdec_as_context_ASSetPropFlags, 3);  SWFDEC_AS_VALUE_SET_NUMBER (&val, NAN);  swfdec_as_object_set_variable (context->global, SWFDEC_AS_STR_NaN, &val);  SWFDEC_AS_VALUE_SET_NUMBER (&val, HUGE_VAL);  swfdec_as_object_set_variable (context->global, SWFDEC_AS_STR_Infinity, &val);  swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_isFinite, 0,      swfdec_as_context_isFinite, 1);  swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_isNaN, 0,      swfdec_as_context_isNaN, 1);  swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_parseInt, 0,      swfdec_as_context_parseInt, 1);}/** * swfdec_as_context_startup: * @context: a #SwfdecAsContext * @version: Flash version to use * * Starts up the context. This function must be called before any Actionscript * is called on @context. The version is responsible for deciding which native * functions and properties are available in the context. **/voidswfdec_as_context_startup (SwfdecAsContext *context, guint version){  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));  g_return_if_fail (context->state == SWFDEC_AS_CONTEXT_NEW);  if (!swfdec_as_stack_push_segment (context))    return;  context->version = version;  /* get the necessary objects up to define objects and functions sanely */  swfdec_as_function_init_context (context, version);  swfdec_as_object_init_context (context, version);  /* define the global object and other important ones */  swfdec_as_context_init_global (context, version);  swfdec_as_array_init_context (context, version);  /* define the type objects */  swfdec_as_boolean_init_context (context, version);  swfdec_as_number_init_context (context, version);  swfdec_as_string_init_context (context, version);  /* define the rest */  swfdec_as_math_init_context (context, version);  if (context->state == SWFDEC_AS_CONTEXT_NEW)    context->state = SWFDEC_AS_CONTEXT_RUNNING;}

⌨️ 快捷键说明

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