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

📄 swfdec_script.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
  cx->fp->sp--;  movie = swfdec_action_get_target (cx);  if (movie) {    int frame = swfdec_value_to_frame (cx, movie, val);    guint jump = data[2];    guint loaded;    if (frame < 0)      return JS_TRUE;    if (SWFDEC_IS_ROOT_MOVIE (movie)) {      SwfdecDecoder *dec = SWFDEC_ROOT_MOVIE (movie)->decoder;      loaded = dec->frames_loaded;      g_assert (loaded <= movie->n_frames);    } else {      loaded = movie->n_frames;    }    if (loaded < (guint) frame)      swfdec_script_skip_actions (cx, jump);  } else {    SWFDEC_ERROR ("no movie to WaitForFrame2 on");  }  return JS_TRUE;}static JSBoolswfdec_action_wait_for_frame (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecMovie *movie = swfdec_action_get_target (cx);  guint frame, jump, loaded;  if (len != 3) {    SWFDEC_ERROR ("WaitForFrame action length invalid (is %u, should be 3", len);    return JS_TRUE;  }  if (movie == NULL) {    SWFDEC_ERROR ("no movie for WaitForFrame");    return JS_TRUE;  }  frame = GUINT16_FROM_LE (*((guint16 *) data));  jump = data[2];  if (SWFDEC_IS_ROOT_MOVIE (movie)) {    SwfdecDecoder *dec = SWFDEC_ROOT_MOVIE (movie)->decoder;    loaded = dec->frames_loaded;    g_assert (loaded <= movie->n_frames);  } else {    loaded = movie->n_frames;  }  if (loaded < frame)    swfdec_script_skip_actions (cx, jump);  return JS_TRUE;}static JSBoolswfdec_action_constant_pool (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecConstantPool *pool;  pool = swfdec_constant_pool_new_from_action (data, len);  if (pool == NULL)    return JS_FALSE;  if (cx->fp->constant_pool)    swfdec_constant_pool_free (cx->fp->constant_pool);  cx->fp->constant_pool = pool;  return JS_TRUE;}static JSBoolswfdec_action_push (JSContext *cx, guint action, const guint8 *data, guint len){  /* FIXME: supply API for this */  SwfdecBits bits;  guint stackspace = cx->fp->spend - cx->fp->sp;  swfdec_bits_init_data (&bits, data, len);  while (swfdec_bits_left (&bits) && stackspace-- > 0) {    guint type = swfdec_bits_get_u8 (&bits);    SWFDEC_LOG ("push type %u", type);    switch (type) {      case 0: /* string */	{	  const char *s = swfdec_bits_skip_string (&bits);	  if (!swfdec_action_push_string (cx, s))	    return JS_FALSE;	  break;	}      case 1: /* float */	{	  double d = swfdec_bits_get_float (&bits);	  if (!JS_NewDoubleValue (cx, d, cx->fp->sp))	    return JS_FALSE;	  cx->fp->sp++;	  break;	}      case 2: /* null */	*cx->fp->sp++ = JSVAL_NULL;	break;      case 3: /* undefined */	*cx->fp->sp++ = JSVAL_VOID;	break;      case 4: /* register */	{	  guint regnum = swfdec_bits_get_u8 (&bits);	  if (!swfdec_action_has_register (cx, regnum)) {	    SWFDEC_ERROR ("cannot Push register %u: not enough registers", regnum);	    return JS_FALSE;	  }	  *cx->fp->sp++ = cx->fp->vars[regnum];	  break;	}      case 5: /* boolean */	*cx->fp->sp++ = swfdec_bits_get_u8 (&bits) ? JSVAL_TRUE : JSVAL_FALSE;	break;      case 6: /* double */	{	  double d = swfdec_bits_get_double (&bits);	  if (!JS_NewDoubleValue (cx, d, cx->fp->sp))	    return JS_FALSE;	  cx->fp->sp++;	  break;	}      case 7: /* 32bit int */	{	  int i = swfdec_bits_get_u32 (&bits);	  *cx->fp->sp++ = INT_TO_JSVAL (i);	  break;	}      case 8: /* 8bit ConstantPool address */	{	  guint i = swfdec_bits_get_u8 (&bits);	  SwfdecConstantPool *pool = cx->fp->constant_pool;	  if (pool == NULL) {	    SWFDEC_ERROR ("no constant pool to push from");	    return JS_FALSE;	  }	  if (i >= swfdec_constant_pool_size (pool)) {	    SWFDEC_ERROR ("constant pool index %u too high - only %u elements",		i, swfdec_constant_pool_size (pool));	    return JS_FALSE;	  }	  if (!swfdec_action_push_string (cx, swfdec_constant_pool_get (pool, i)))	    return JS_FALSE;	  break;	}      case 9: /* 16bit ConstantPool address */	{	  guint i = swfdec_bits_get_u16 (&bits);	  SwfdecConstantPool *pool = cx->fp->constant_pool;	  if (pool == NULL) {	    SWFDEC_ERROR ("no constant pool to push from");	    return JS_FALSE;	  }	  if (i >= swfdec_constant_pool_size (pool)) {	    SWFDEC_ERROR ("constant pool index %u too high - only %u elements",		i, swfdec_constant_pool_size (pool));	    return JS_FALSE;	  }	  if (!swfdec_action_push_string (cx, swfdec_constant_pool_get (pool, i)))	    return JS_FALSE;	  break;	}      default:	SWFDEC_ERROR ("Push: type %u not implemented", type);	return JS_FALSE;    }  }  return swfdec_bits_left (&bits) ? JS_FALSE : JS_TRUE;}static JSBoolswfdec_action_get_variable (JSContext *cx, guint action, const guint8 *data, guint len){  const char *s;  s = swfdec_js_to_string (cx, cx->fp->sp[-1]);  if (s == NULL)    return JS_FALSE;  cx->fp->sp[-1] = swfdec_js_eval (cx, NULL, s);#ifdef SWFDEC_WARN_MISSING_PROPERTIES  if (cx->fp->sp[-1] == JSVAL_VOID) {    SWFDEC_WARNING ("no variable named %s", s);  }#endif  return JS_TRUE;}static JSBoolswfdec_action_set_variable (JSContext *cx, guint action, const guint8 *data, guint len){  const char *s;  s = swfdec_js_to_string (cx, cx->fp->sp[-2]);  if (s == NULL)    return JS_FALSE;  swfdec_js_eval_set (cx, NULL, s, cx->fp->sp[-1]);  cx->fp->sp -= 2;  return JS_TRUE;}static JSBoolswfdec_action_trace (JSContext *cx, guint action, const guint8 *data, guint len){  SwfdecPlayer *player = JS_GetContextPrivate (cx);  const char *bytes;  bytes = swfdec_js_to_string (cx, cx->fp->sp[-1]);  cx->fp->sp--;  if (bytes == NULL)    return JS_TRUE;  swfdec_player_trace (player, bytes);  return JS_TRUE;}/** * swfdec_action_invoke: * @cx: the #JSContext * @n_args: number of arguments * * This function is similar to js_Invoke, however it uses a reversed stack * order. sp[-1] has to be the function to call, sp[-2] will be the object the  * function is called on, sp[-3] is the first argument, followed by the rest of * the arguments. The function removes all of these argumends from the stack  * and pushes the return value on top. * * Returns: JS_TRUE on success, JS_FALSE on failure. **/static JSBoolswfdec_action_call (JSContext *cx, guint n_args, guint flags){  JSStackFrame *fp = cx->fp;  int i, j;  jsval tmp;  guint stacksize;  stacksize = fp->sp - fp->spbase;  g_assert (stacksize >= 2);  if (n_args + 2 > stacksize) {    SWFDEC_WARNING ("broken script. Want %u arguments, only got %u", n_args, stacksize - 2);    n_args = stacksize - 2;    if (!swfdec_script_ensure_stack (cx, n_args + 2))      return JS_FALSE;  }  j = -1;  i = - (n_args + 2);  while (i < j) {    tmp = fp->sp[j];    fp->sp[j] = fp->sp[i];    fp->sp[i] = tmp;    j--;    i++;  }  return js_Invoke (cx, n_args, flags);}/* FIXME: lots of overlap with swfdec_action_call_method */static JSBoolswfdec_action_call_function (JSContext *cx, guint action, const guint8 *data, guint len){  JSStackFrame *fp = cx->fp;  const char *s;  guint32 n_args;  JSObject *obj, *pobj;  JSProperty *prop;  jsval fun;  JSAtom *atom;    if (!swfdec_script_ensure_stack (cx, 2))    return JS_FALSE;  s = swfdec_js_to_string (cx, fp->sp[-1]);  if (s == NULL)    return JS_FALSE;  if (!JS_ValueToECMAUint32 (cx, fp->sp[-2], &n_args))    return JS_FALSE;    if (!(atom = js_Atomize (cx, s, strlen (s), 0)) ||      !js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop))    return JS_FALSE;  if (!JS_GetProperty (cx, obj, s, &fun))    return JS_FALSE;  if (!JSVAL_IS_OBJECT (fun)) {    /* FIXME: figure out what class we operate on */    SWFDEC_WARNING ("%s is not a function", s);  }  fp->sp[-1] = fun;  fp->sp[-2] = OBJECT_TO_JSVAL (obj);  swfdec_action_call (cx, n_args, 0);  return JS_TRUE;}static JSBoolswfdec_action_call_method (JSContext *cx, guint action, const guint8 *data, guint len){  JSStackFrame *fp = cx->fp;  const char *s;  guint32 n_args;  JSObject *obj;  jsval fun;    if (!swfdec_script_ensure_stack (cx, 3))    return JS_FALSE;  if (fp->sp[-1] == JSVAL_VOID) {    s = "";  } else {    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], &obj))    return JS_FALSE;  if (obj == NULL)    goto fail;  if (s[0] == '\0') {    fun = OBJECT_TO_JSVAL (obj);  } else {    if (!JS_GetProperty (cx, obj, s, &fun))      return JS_FALSE;    if (!JSVAL_IS_OBJECT (fun)) {      SWFDEC_WARNING ("%s:%s is not a function", JS_GetClass (obj)->name, s);    }  }  fp->sp--;  fp->sp[-1] = fun;  fp->sp[-2] = OBJECT_TO_JSVAL (obj);  swfdec_action_call (cx, n_args, 0);  return JS_TRUE;fail:  fp->sp -= 2 + n_args;  fp->sp[-1] = JSVAL_VOID;  return JS_TRUE;}static JSBoolswfdec_action_pop (JSContext *cx, guint action, const guint8 *data, guint len){  cx->fp->sp--;  return JS_TRUE;}static const char *swfdec_eval_jsval (JSContext *cx, JSObject *obj, jsval *val){  if (JSVAL_IS_STRING (*val)) {    const char *bytes = swfdec_js_to_string (cx, *val);    if (bytes == NULL)      return NULL;    *val = swfdec_js_eval (cx, obj, bytes);    return bytes;  } else {    if (obj == NULL) {      obj = OBJ_THIS_OBJECT (cx, cx->fp->scopeChain);    }    *val = OBJECT_TO_JSVAL (obj);    return ".";  }}static const char *properties[22] = {  "_x", "_y", "_xscale", "_yscale", "_currentframe",  "_totalframes", "_alpha", "_visible", "_width", "_height",  "_rotation", "_target", "_framesloaded", "_name", "_droptarget",  "_url", "_highquality", "_focusrect", "_soundbuftime", "_quality",  "_xmouse", "_ymouse"};static JSBoolswfdec_action_get_property (JSContext *cx, guint action, const guint8 *data, guint len){  jsval val;  SwfdecMovie *movie;  JSObject *jsobj;  guint32 id;  const char *bytes;  if (!JS_ValueToECMAUint32 (cx,  cx->fp->sp[-1], &id))    return JS_FALSE;  val = cx->fp->sp[-2];  bytes = swfdec_eval_jsval (cx, NULL, &val);  if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18)) {    SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id);    goto out;  }  if (bytes == NULL)    return JS_FALSE;  if (*bytes == '\0') {    JSObject *pobj;    JSProperty *prop;    JSAtom *atom = js_Atomize (cx, properties[id], strlen (properties[id]), 0);    if (atom == NULL)      return JS_FALSE;    if (!js_FindProperty (cx, (jsid) atom, &jsobj, &pobj, &prop))      return JS_FALSE;    if (!prop)      return JS_FALSE;    if (!OBJ_GET_PROPERTY (cx, jsobj, (jsid) prop->id, &val))      return JS_FALSE;  } else {    movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE);    if (movie == NULL) {      SWFDEC_WARNING ("specified target does not reference a movie clip");      goto out;    }    jsobj = JSVAL_TO_OBJECT (val);    val = JSVAL_VOID;    if (!JS_GetProperty (cx, jsobj, properties[id], &val))      return JS_FALSE;  }out:  cx->fp->sp -= 1;  cx->fp->sp[-1] = val;  return JS_TRUE;}static JSBoolswfdec_action_set_property (JSContext *cx, guint action, const guint8 *data, guint len){  jsval val;  SwfdecMovie *movie;  JSObject *jsobj;  guint32 id;  const char *bytes;  val = cx->fp->sp[-3];  if (!JS_ValueToECMAUint32 (cx,  cx->fp->sp[-2], &id))    return JS_FALSE;  bytes = swfdec_eval_jsval (cx, NULL, &val);  if (!bytes)    return JS_FALSE;  if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18)) {    SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id);    goto out;  }  if (*bytes == '\0' || *bytes == '.')    val = OBJECT_TO_JSVAL (cx->fp->varobj);  movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE);  if (movie == NULL) {    SWFDEC_WARNING ("specified target does not reference a movie clip");    goto out;  }  jsobj = JSVAL_TO_OBJECT (val);  if (!JS_SetProperty (cx, jsobj, properties[id], &cx->fp->sp[-1]))    return JS_FALSE;out:  cx->fp->sp -= 3;  return JS_TRUE;}static JSBoolswfdec_action_binary (JSContext *cx, guint action, const guint8 *data, guint len){  jsval lval, rval;  double l, r;  rval = cx->fp->sp[-1];  lval = cx->fp->sp[-2];  if (((SwfdecScript *) cx->fp->swf)->version < 7) {    l = swfdec_value_to_number (cx, lval);    r = swfdec_value_to_number (cx, rval);  } else {    if (!swfdec_value_to_number_7 (cx, lval, &l) ||        !swfdec_value_to_number_7 (cx, rval, &r))      return JS_FALSE;  }  cx->fp->sp--;  switch (action) {    case 0x0a:      l = l + r;      break;    case 0x0b:      l = l - r;      break;    case 0x0c:      l = l * r;      break;    case 0x0d:      if (((SwfdecScript *) cx->fp->swf)->version < 5) {	if (r == 0) {	  JSString *str = JS_InternString (cx, "#ERROR#");	  if (str == NULL)	    return JS_FALSE;	  cx->fp->sp[-1] = STRING_TO_JSVAL (str);	  return JS_TRUE;

⌨️ 快捷键说明

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