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

📄 swfdec_script.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
    return JS_FALSE;  if (!swfdec_eval_jsval (cx, NULL, &fp->sp[-1]))    return JS_FALSE;  if (swfdec_value_to_number (cx, fp->sp[-3])) {    jsval tmp;    if (!swfdec_script_ensure_stack (cx, 7))      return JS_FALSE;    n_args = 5;    /* yay for order */    tmp = fp->sp[-4];    fp->sp[-4] = fp->sp[-7];    fp->sp[-7] = tmp;    tmp = fp->sp[-6];    fp->sp[-6] = fp->sp[-5];    fp->sp[-5] = tmp;  }  if (!JSVAL_IS_OBJECT (fp->sp[-1]) || JSVAL_IS_NULL (fp->sp[-1])) {    fp->sp -= n_args + 2;    return JS_TRUE;  }  fp->sp[-3] = fp->sp[-2];  fp->sp[-2] = fp->sp[-1];  if (!JS_GetProperty (cx, JSVAL_TO_OBJECT (fp->sp[-2]), "startDrag", &fp->sp[-1]))    return JS_FALSE;  swfdec_action_call (cx, n_args, 0);  fp->sp--;  return JS_TRUE;}static JSBoolswfdec_action_end_drag (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecPlayer *player = JS_GetContextPrivate (cx);  swfdec_player_set_drag_movie (player, NULL, FALSE, NULL);  return JS_TRUE;}static JSBoolswfdec_action_stop_sounds (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecPlayer *player = JS_GetContextPrivate (cx);  swfdec_player_stop_all_sounds (player);  return JS_TRUE;}static JSBoolswfdec_action_new_object (JSContext *cx, guint action, const guint8 *data, guint len){  JSStackFrame *fp = cx->fp;  jsval constructor;  JSObject *object;  guint n_args;  const char *name;  if (!swfdec_script_ensure_stack (cx, 2))    return JS_FALSE;  constructor = fp->sp[-1];  name = swfdec_eval_jsval (cx, NULL, &constructor);  if (name == NULL)    return JS_FALSE;  if (!JS_ValueToECMAUint32 (cx, fp->sp[-2], &n_args))    return JS_FALSE;  if (constructor == JSVAL_VOID) {    SWFDEC_WARNING ("no constructor for %s", name);  }  fp->sp[-1] = constructor;  if (!swfdec_js_construct_object (cx, NULL, constructor, &object))    return JS_FALSE;  if (object == NULL)    goto fail;  fp->sp[-2] = OBJECT_TO_JSVAL (object);  if (!swfdec_action_call (cx, n_args, JSINVOKE_CONSTRUCT))    return JS_FALSE;  fp->sp[-1] = OBJECT_TO_JSVAL (object);  return JS_TRUE;fail:  fp->sp -= n_args + 1;  fp->sp[-1] = JSVAL_VOID;  return JS_TRUE;}static JSBoolswfdec_action_new_method (JSContext *cx, guint action, const guint8 *data, guint len){  JSStackFrame *fp = cx->fp;  const char *s;  guint32 n_args;  JSObject *object;  jsval constructor;    if (!swfdec_script_ensure_stack (cx, 3))    return JS_FALSE;  s = swfdec_js_to_string (cx, fp->sp[-1]);  if (s == NULL)    return JS_FALSE;  if (!JS_ValueToECMAUint32 (cx, fp->sp[-3], &n_args))    return JS_FALSE;    if (!JS_ValueToObject (cx, fp->sp[-2], &object))    return JS_FALSE;  if (object == NULL)    goto fail;  if (s[0] == '\0') {    constructor = OBJECT_TO_JSVAL (object);  } else {    if (!JS_GetProperty (cx, object, s, &constructor))      return JS_FALSE;    if (!JSVAL_IS_OBJECT (constructor)) {      SWFDEC_WARNING ("%s:%s is not a function", JS_GetClass (object)->name, s);    }  }  fp->sp[-1] = OBJECT_TO_JSVAL (constructor);  if (!swfdec_js_construct_object (cx, NULL, constructor, &object))    return JS_FALSE;  if (object == NULL)    goto fail;  fp->sp[-2] = OBJECT_TO_JSVAL (object);  if (!swfdec_action_call (cx, n_args, JSINVOKE_CONSTRUCT))    return JS_FALSE;  fp->sp[-1] = OBJECT_TO_JSVAL (object);  return JS_TRUE;fail:  fp->sp -= 2 + n_args;  fp->sp[-1] = JSVAL_VOID;  return JS_TRUE;}static JSBoolswfdec_action_init_object (JSContext *cx, guint action, const guint8 *data, guint len){  JSStackFrame *fp = cx->fp;  JSObject *object;  guint n_args;  gulong i;  if (!JS_ValueToECMAUint32 (cx, fp->sp[-1], &n_args))    return JS_FALSE;  if (!swfdec_script_ensure_stack (cx, 2 * n_args + 1))    return JS_FALSE;  object = JS_NewObject (cx, &js_ObjectClass, NULL, NULL);  if (object == NULL)    return JS_FALSE;  for (i = 0; i < n_args; i++) {    const char *s = swfdec_js_to_string (cx, fp->sp[-3 - 2 * i]);    if (s == NULL)      return JS_FALSE;    if (!JS_SetProperty (cx, object, s, &fp->sp[-2 - 2 * i]))      return JS_FALSE;  }  fp->sp -= 2 * n_args;  fp->sp[-1] = OBJECT_TO_JSVAL (object);  return JS_TRUE;}static JSBoolswfdec_action_init_array (JSContext *cx, guint action, const guint8 *data, guint len){  JSStackFrame *fp = cx->fp;  JSObject *array;  int i, j;  guint n_items;  if (!JS_ValueToECMAUint32 (cx, fp->sp[-1], &n_items))    return JS_FALSE;  if (!swfdec_script_ensure_stack (cx, n_items + 1))    return JS_FALSE;  /* items are the wrong order on the stack */  j = - 1 - n_items;  for (i = - 2; i > j; i--, j++) {    jsval tmp = fp->sp[i];    fp->sp[i] = fp->sp[j];    fp->sp[j] = tmp;  }  array = JS_NewArrayObject (cx, n_items, fp->sp - n_items - 1);  if (array == NULL)    return JS_FALSE;  fp->sp -= n_items;  fp->sp[-1] = OBJECT_TO_JSVAL (array);  return JS_TRUE;}static JSBoolswfdec_action_define_function (JSContext *cx, guint action,    const guint8 *data, guint len){  const char *function_name;  guint i, n_args, size;  SwfdecBits bits;  JSFunction *fun;  SwfdecScript *script;  JSObject *scope;  gboolean has_preloads = FALSE;  guint flags = 0;  guint8 *preloads = NULL;  gboolean v2 = (action == 0x8e);  swfdec_bits_init_data (&bits, data, len);  function_name = swfdec_bits_get_string (&bits);  if (function_name == NULL) {    SWFDEC_ERROR ("could not parse function name");    return JS_FALSE;  }  n_args = swfdec_bits_get_u16 (&bits);  scope = cx->fp->scopeChain;  script = cx->fp->swf;  if (script->version == 5) {    /* In Flash 5 there's only the root scope as a parent scope */    JSObject *parent;    /* FIXME: this implementation is hacky (but it works) */    while (JS_GetClass (scope) == &js_CallClass && (parent = JS_GetParent (cx, scope)))      scope = parent;  }  if (*function_name == '\0') {    /* anonymous function */    fun = JS_NewFunction (cx, NULL, n_args, JSFUN_LAMBDA | JSFUN_HEAVYWEIGHT,	scope, NULL);  } else {    /* named function */    fun = JS_NewFunction (cx, NULL, n_args, JSFUN_HEAVYWEIGHT, 	scope, function_name);  }  if (fun == NULL)    return JS_FALSE;  if (v2) {    fun->nvars = swfdec_bits_get_u8 (&bits) + 1;    flags = swfdec_bits_get_u16 (&bits);    preloads = g_new0 (guint8, n_args);  } else {    fun->nvars = 5;  }  for (i = 0; i < n_args; i++) {    JSAtom *atom;    const char *arg_name;    if (v2) {      guint preload = swfdec_bits_get_u8 (&bits);      if (preload && preload >= fun->nvars) {	SWFDEC_ERROR ("argument %u is preloaded into register %u out of %u", 	    i, preload, fun->nvars);	return JS_FALSE;      }      if (preload != 0) {	preloads[i] = preload;	swfdec_bits_skip_string (&bits);	has_preloads = TRUE;	continue;      }    }    arg_name = swfdec_bits_skip_string (&bits);    if (arg_name == NULL || *arg_name == '\0') {      SWFDEC_ERROR ("empty argument name not allowed");      return JS_FALSE;    }    /* FIXME: check duplicate arguments */    atom = js_Atomize (cx, arg_name, strlen (arg_name), 0);    if (atom == NULL)      return JS_FALSE;    if (!js_AddNativeProperty (cx, fun->object, (jsid) atom,	js_GetArgument, js_SetArgument, SPROP_INVALID_SLOT,	JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_SHARED,	SPROP_HAS_SHORTID, i)) {      return JS_FALSE;    }  }  if (preloads && !has_preloads) {    g_free (preloads);    preloads = NULL;  }  size = swfdec_bits_get_u16 (&bits);  /* check the script can be created */  if (script->buffer->data + script->buffer->length < cx->fp->pc + 3 + len + size) {    SWFDEC_ERROR ("size of function is too big");    return FALSE;  } else {    /* create the script */    const char *name = NULL;    SwfdecBuffer *buffer = swfdec_buffer_new_subbuffer (script->buffer, 	cx->fp->pc + 3 + len - script->buffer->data, size);    swfdec_bits_init (&bits, buffer);    if (*function_name) {      name = function_name;    } else if (cx->fp->sp > cx->fp->spbase) {      /* 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 (JSVAL_IS_STRING (cx->fp->sp[-1]))	name = JS_GetStringBytes (JSVAL_TO_STRING (cx->fp->sp[-1]));    }    if (name == NULL)      name = "unnamed_function";    script = swfdec_script_new (&bits, name, ((SwfdecScript *) cx->fp->swf)->version);    swfdec_buffer_unref (buffer);  }  if (script == NULL) {    SWFDEC_ERROR ("failed to create script");    g_free (preloads);    return JS_FALSE;  }  if (cx->fp->constant_pool) {    script->constant_pool = swfdec_constant_pool_get_area (cx->fp->swf,	cx->fp->constant_pool);  }  script->flags = flags;  script->preloads = preloads;  fun->swf = script;  swfdec_script_add_to_player (script, JS_GetContextPrivate (cx));  /* attach the function */  if (*function_name == '\0') {    if (cx->fp->sp >= cx->fp->spend) {      SWFDEC_ERROR ("not enough stack space available");      return JS_FALSE;    }    *cx->fp->sp++ = OBJECT_TO_JSVAL (fun->object);  } else {    jsval val = OBJECT_TO_JSVAL (fun->object);    if (!JS_SetProperty (cx, cx->fp->varobj, function_name, &val))      return JS_FALSE;  }  /* update current context */  cx->fp->pc += 3 + len + size;  return JS_TRUE;}static JSBoolswfdec_action_bitwise (JSContext *cx, guint action, const guint8 *data, guint len){  guint32 a, b;  double d;  if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-1], &a) ||      !JS_ValueToECMAUint32 (cx, cx->fp->sp[-2], &b))    return JS_FALSE;  switch (action) {    case 0x60:      d = (int) (a & b);      break;    case 0x61:      d = (int) (a | b);      break;    case 0x62:      d = (int) (a ^ b);      break;    default:      g_assert_not_reached ();      return JS_FALSE;  }  cx->fp->sp--;  return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);}static JSBoolswfdec_action_shift (JSContext *cx, guint action, const guint8 *data, guint len){  guint32 amount, value;  double d;  if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-1], &amount) ||      !JS_ValueToECMAUint32 (cx, cx->fp->sp[-2], &value))    return JS_FALSE;  amount &= 31;  switch (action) {    case 0x63:      d = value << amount;      break;    case 0x64:      d = ((gint) value) >> amount;      break;    case 0x65:      d = ((guint) value) >> amount;      break;    default:      g_assert_not_reached ();      return JS_FALSE;  }  cx->fp->sp--;  return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);}static JSBoolswfdec_action_to_integer (JSContext *cx, guint action, const guint8 *data, guint len){  double d = swfdec_value_to_number (cx, cx->fp->sp[-1]);  return JS_NewNumberValue (cx, (int) d, &cx->fp->sp[-1]);}static JSBoolswfdec_action_target_path (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecMovie *movie = swfdec_scriptable_from_jsval (cx, cx->fp->sp[-1], SWFDEC_TYPE_MOVIE);  if (movie == NULL) {    cx->fp->sp[-1] = JSVAL_VOID;  } else {    char *s = swfdec_movie_get_path (movie);    JSString *string = JS_NewStringCopyZ (cx, s);    g_free (s);    if (string == NULL)      return JS_FALSE;    cx->fp->sp[-1] = STRING_TO_JSVAL (string);  }  return JS_TRUE;}static JSBoolswfdec_action_define_local (JSContext *cx, guint action, const guint8 *data, guint len){  const char *name;  g_assert (cx->fp->scopeChain != NULL);  name = swfdec_js_to_string (cx, cx->fp->sp[-2]);  if (name == NULL)    return JS_FALSE;  if (!JS_SetProperty (cx, cx->fp->scopeChain, name, &cx->fp->sp[-1]))    return JS_FALSE;  cx->fp->sp -= 2;  return JS_TRUE;}static JSBoolswfdec_action_define_local2 (JSContext *cx, guint action, const guint8 *data, guint len){  const char *name;  jsval val = JSVAL_VOID;  g_assert (cx->fp->scopeChain != NULL);  name = swfdec_js_to_string (cx, cx->fp->sp[-1]);  if (name == NULL)    return JS_FALSE;  if (!JS_SetProperty (cx, cx->fp->scopeChain, name, &val))    return JS_FALSE;  cx->fp->sp--;  return JS_TRUE;}static JSBoolswfdec_action_return (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecScript *script = cx->fp->swf;  cx->fp->rval = cx->fp->sp[-1];  cx->fp->pc = script->buffer->data + script->buffer->length;  cx->fp->sp--;  return JS_TRUE;}static JSBoolswfdec_action_delete (JSContext *cx, guint action, const guint8 *data, guint len){  const char *name;    cx->fp->sp -= 2;  name = swfdec_js_to_string (cx, cx->fp->sp[1]);  if (name == NULL)    return JS_FALSE;  if (!JSVAL_IS_OBJECT (cx->fp->sp[0]))    return JS_TRUE;  return JS_DeleteProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[0]), name);}static JSBoolswfdec_action_delete2 (JSContext *cx, guint action, const guint8 *data, guint len){  const char *name;  JSObject *obj, *pobj;  JSProperty *prop;  JSAtom *atom;    cx->fp->sp -= 1;  name = swfdec_js_to_string (cx, cx->fp->sp[1]);  if (name == NULL)    return JS_FALSE;  if (!(atom = js_Atomize (cx, name, strlen (name), 0)) ||      !js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop))    return JS_FALSE;  if (!pobj)    return JS_TRUE;  return JS_DeleteProperty (cx, pobj, name);}

⌨️ 快捷键说明

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