[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10928: Fix crash due to unchecked r
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10928: Fix crash due to unchecked return from to_object(). |
Date: |
Wed, 27 May 2009 13:10:37 +0200 |
User-agent: |
Bazaar (1.13.1) |
------------------------------------------------------------
revno: 10928
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-05-27 13:10:37 +0200
message:
Fix crash due to unchecked return from to_object().
Add some AS3 constants and AVM2 debugging.
modified:
libcore/asobj/flash/display/StageAlign_as.cpp
libcore/asobj/flash/display/StageScaleMode_as.cpp
libcore/swf/DoABCTag.h
libcore/vm/Machine.cpp
------------------------------------------------------------
revno: 10927.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Wed 2009-05-27 11:40:03 +0200
message:
Fix crashes caused by not checking existence of object.
modified:
libcore/vm/Machine.cpp
------------------------------------------------------------
revno: 10927.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Wed 2009-05-27 12:11:06 +0200
message:
Add more debugging messages for AVM2.
Add constants to StageScaleMode for testing Machine.
modified:
libcore/asobj/flash/display/StageScaleMode_as.cpp
libcore/vm/Machine.cpp
------------------------------------------------------------
revno: 10927.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Wed 2009-05-27 12:28:19 +0200
message:
Add StageAlign constants.
More debugging.
modified:
libcore/asobj/flash/display/StageAlign_as.cpp
libcore/swf/DoABCTag.h
libcore/vm/Machine.cpp
------------------------------------------------------------
revno: 10927.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Wed 2009-05-27 12:48:25 +0200
message:
More debugging.
modified:
libcore/vm/Machine.cpp
=== modified file 'libcore/asobj/flash/display/StageAlign_as.cpp'
--- a/libcore/asobj/flash/display/StageAlign_as.cpp 2009-05-24 22:25:59
+0000
+++ b/libcore/asobj/flash/display/StageAlign_as.cpp 2009-05-27 10:28:19
+0000
@@ -27,62 +27,39 @@
#include "smart_ptr.h" // for boost intrusive_ptr
#include "builtin_function.h" // need builtin_function
#include "GnashException.h" // for ActionException
+#include "Object.h"
namespace gnash {
// Forward declarations
namespace {
- as_value stagealign_ctor(const fn_call& fn);
- void attachStageAlignInterface(as_object& o);
void attachStageAlignStaticInterface(as_object& o);
- as_object* getStageAlignInterface();
-
}
// extern (used by Global.cpp)
-void stagealign_class_init(as_object& global)
+void
+stagealign_class_init(as_object& where)
{
- static boost::intrusive_ptr<builtin_function> cl;
-
- if (!cl) {
- cl = new builtin_function(&stagealign_ctor, getStageAlignInterface());
- attachStageAlignStaticInterface(*cl);
- }
-
- // Register _global.StageAlign
- global.init_member("StageAlign", cl.get());
+ boost::intrusive_ptr<as_object> obj = new as_object(getObjectInterface());
+ attachStageAlignStaticInterface(*obj);
+
+ where.init_member("StageAlign", obj.get());
}
namespace {
void
-attachStageAlignInterface(as_object& o)
-{
-}
-
-void
attachStageAlignStaticInterface(as_object& o)
{
-
-}
-
-as_object*
-getStageAlignInterface()
-{
- static boost::intrusive_ptr<as_object> o;
- if ( ! o ) {
- o = new as_object();
- attachStageAlignInterface(*o);
- }
- return o.get();
-}
-
-as_value
-stagealign_ctor(const fn_call& fn)
-{
- boost::intrusive_ptr<as_object> obj = new StageAlign_as;
-
- return as_value(obj.get()); // will keep alive
+ // TODO: flags
+ o.init_member("BOTTOM", "B");
+ o.init_member("BOTTOM_LEFT", "BL");
+ o.init_member("BOTTOM_RIGHT", "BR");
+ o.init_member("LEFT", "L");
+ o.init_member("RIGHT", "R");
+ o.init_member("TOP", "T");
+ o.init_member("TOP_LEFT", "TL");
+ o.init_member("TOP_RIGHT", "TR");
}
} // anonymous namespace
=== modified file 'libcore/asobj/flash/display/StageScaleMode_as.cpp'
--- a/libcore/asobj/flash/display/StageScaleMode_as.cpp 2009-05-24 22:25:59
+0000
+++ b/libcore/asobj/flash/display/StageScaleMode_as.cpp 2009-05-27 10:11:06
+0000
@@ -27,62 +27,35 @@
#include "smart_ptr.h" // for boost intrusive_ptr
#include "builtin_function.h" // need builtin_function
#include "GnashException.h" // for ActionException
+#include "Object.h"
namespace gnash {
// Forward declarations
namespace {
- as_value stagescalemode_ctor(const fn_call& fn);
- void attachStageScaleModeInterface(as_object& o);
void attachStageScaleModeStaticInterface(as_object& o);
as_object* getStageScaleModeInterface();
-
}
-// extern (used by Global.cpp)
-void stagescalemode_class_init(as_object& global)
+void
+stagescalemode_class_init(as_object& where)
{
- static boost::intrusive_ptr<builtin_function> cl;
-
- if (!cl) {
- cl = new builtin_function(&stagescalemode_ctor,
getStageScaleModeInterface());
- attachStageScaleModeStaticInterface(*cl);
- }
-
- // Register _global.StageScaleMode
- global.init_member("StageScaleMode", cl.get());
+ boost::intrusive_ptr<as_object> obj = new as_object(getObjectInterface());
+ attachStageScaleModeStaticInterface(*obj);
+
+ where.init_member("StageScaleMode", obj.get());
}
+
namespace {
void
-attachStageScaleModeInterface(as_object& o)
-{
-}
-
-void
attachStageScaleModeStaticInterface(as_object& o)
{
-
-}
-
-as_object*
-getStageScaleModeInterface()
-{
- static boost::intrusive_ptr<as_object> o;
- if ( ! o ) {
- o = new as_object();
- attachStageScaleModeInterface(*o);
- }
- return o.get();
-}
-
-as_value
-stagescalemode_ctor(const fn_call& fn)
-{
- boost::intrusive_ptr<as_object> obj = new StageScaleMode_as;
-
- return as_value(obj.get()); // will keep alive
+ o.init_member("EXACT_FIT", "exactFit");
+ o.init_member("NO_BORDER", "noBorder");
+ o.init_member("NO_SCALE", "noScale");
+ o.init_member("SHOW_ALL", "showAll");
}
} // anonymous namespace
=== modified file 'libcore/swf/DoABCTag.h'
--- a/libcore/swf/DoABCTag.h 2009-05-19 10:18:34 +0000
+++ b/libcore/swf/DoABCTag.h 2009-05-27 10:28:19 +0000
@@ -41,9 +41,9 @@
{
public:
- virtual void execute(MovieClip* /*m*/, DisplayList& /* dlist */) const
+ virtual void execute(MovieClip* m, DisplayList& /* dlist */) const
{
- VM& vm = VM::get();
+ VM& vm = m->getVM();
log_debug("getting machine.");
Machine *mach = vm.getMachine();
as_object* global = vm.getGlobal();
@@ -51,12 +51,7 @@
mABC->prepare(mach);
log_debug("Begin execute abc_block.");
-// log_debug("Getting entry script.");
-// asClass* start_script = a.mScripts.back();
-// log_debug("Getting constructor.");
-// asMethod* method = start_script->getConstructor();
-// log_debug("Loding code stream.");
- mach->initMachine(mABC,global);
+ mach->initMachine(mABC, global);
log_debug("Executing machine...");
mach->execute();
}
=== modified file 'libcore/vm/Machine.cpp'
--- a/libcore/vm/Machine.cpp 2009-05-25 09:01:34 +0000
+++ b/libcore/vm/Machine.cpp 2009-05-27 10:48:25 +0000
@@ -800,6 +800,15 @@
as_object *obj = mStack.top(1).to_object().get();
const boost::uint32_t index =
mStack.top(0).to_number<boost::uint32_t>();
+
+ if (!obj) {
+ // TODO: check what to do here.
+ log_debug("ABC_ACTION_NEXTNAME: expecting object on "
+ "stack, got %s", mStack.top(1));
+ mStack.drop(2);
+ break;
+ }
+
mStack.drop(1);
const Property *b = obj->getByIndex(index);
if (b) mStack.top(0) = mST.value(b->getName());
@@ -824,6 +833,7 @@
boost::uint32_t index =
mStack.top(0).to_number<boost::uint32_t>();
mStack.drop(1);
+ assert(obj);
mStack.top(0) = obj->nextIndex(index);
break;
}
@@ -996,14 +1006,16 @@
/// ns -- Namespace object from namespace_pool[index]
case SWF::ABC_ACTION_PUSHNAMESPACE:
{
- asNamespace *ns = pool_namespace(mStream->read_V32(),
mPoolObject);
+ asNamespace *ns = pool_namespace(mStream->read_V32(),
+ mPoolObject);
mStack.grow(1);
mStack.top(0) = *ns;
break;
}
/// 0x32 ABC_ACTION_HASNEXT2
- /// Stream: V32 frame location 'objloc' | V32 frame location
'indexloc'
+ /// Stream: V32 frame location 'objloc' | V32 frame location
+ /// 'indexloc'
/// Stack Out:
/// truth -- True if frame[objloc] has key/val pair after
/// frame[indexloc], following delegates (__proto__) objects
@@ -1011,26 +1023,36 @@
/// Frame:
/// Change at objloc to object which possessed next value.
/// Change at indexloc to index (as object) of the next value.
- /// N.B.: A value of '0' for indexloc initializes to the first
logical
- /// property.
+ /// N.B.: A value of '0' for indexloc initializes to the
+ /// first logical property.
case SWF::ABC_ACTION_HASNEXT2:
{
- boost::int32_t oindex = mStream->read_V32();
- boost::int32_t iindex = mStream->read_V32();
- as_value &objv = mRegisters[oindex];
- as_value &indexv = mRegisters[iindex];
- log_abc("Index is %u",indexv.to_number());
- // ENSURE_OBJECT(objv);
- // ENSURE_NUMBER(indexv);
+ const boost::int32_t oindex = mStream->read_V32();
+ const boost::int32_t iindex = mStream->read_V32();
+
+ as_value& objv = mRegisters[oindex];
+ const as_value& indexv = mRegisters[iindex];
+
+ log_abc("HASNEXT2: Object is %s, index is %d",
+ objv, indexv);
+
as_object *obj = objv.to_object().get();
+ if (!obj) {
+ // TODO: Check what to do here.
+ log_error("ABC_ACTION_HASNEXT2: expecting object in "
+ "register %d, got %s", oindex, objv);
+ // Stack is unchanged, so just break? Or push false?
+ // Or throw?
+ break;
+ }
+
boost::uint32_t index =
indexv.to_number<boost::uint32_t>();
- log_abc("Object is %s index is
%u",objv.toDebugString(),index);
- as_object *owner = NULL;
+
+ as_object *owner = 0;
int next = obj->nextIndex(index, &owner);
- log_abc("Next index is %d",next);
- // mStack.grow(1);
+ log_abc("HASNEXT2: Next index is %d", next);
+
if (next) {
- // mStack.top(0).set_bool(true);
push_stack(true);
if (owner) mRegisters[oindex] = owner;
else mRegisters[oindex].set_null();
@@ -1547,28 +1569,29 @@
/// 0x5A ABC_ACTION_NEWCATCH
/// Stream: V32 'catch_id'
/// Stack Out:
- /// vtable -- vtable suitable to catch an exception of type in
catch_id.
+ /// vtable -- vtable suitable to catch an exception of type in
+ /// catch_id.
/// NB: Need more information on how exceptions are set up.
case SWF::ABC_ACTION_NEWCATCH:
{
// TODO: Decide if we need this. (Might be a no-op.)
break;
}
- /// 0x5D ABC_ACTION_FINDPROPSTRICT
- /// 0x5E ABC_ACTION_FINDPROPERTY
- /// Stream: V32 'name_id'
- /// Stack In:
- /// [ns [n]] -- Namespace stuff
- /// Stack Out:
- /// owner -- object which owns property given by looking up the
name_id.
- /// 0x5D is the undefined object if not found
- /// 0x5E throws a ReferenceError if not found
+ /// 0x5D ABC_ACTION_FINDPROPSTRICT
+ /// 0x5E ABC_ACTION_FINDPROPERTY
+ /// Stream: V32 'name_id'
+ /// Stack In:
+ /// [ns [n]] -- Namespace stuff
+ /// Stack Out:
+ /// owner -- object which owns property given by looking
+ /// up the name_id.
+ /// 0x5D is the undefined object if not found
+ /// 0x5E throws a ReferenceError if not found
case SWF::ABC_ACTION_FINDPROPSTRICT:
case SWF::ABC_ACTION_FINDPROPERTY:
{
- // boost::uint32_t property_name = mStream->read_V32();
asName a = pool_name(mStream->read_V32(), mPoolObject);
- find_prop_strict(a);
+ as_value ret = find_prop_strict(a);
/* mStack.drop(completeName(a));
as_object *owner;
Property *b = mCurrentScope->findProperty(a.getABCName(),
@@ -1597,38 +1620,41 @@
// TODO
break;
}
- /// 0x60 ABC_ACTION_GETLEX
- /// Stream: V32 'name_id' (no ns expansion)
- /// Stack Out:
- /// property -- The result of 0x5D (ABC_ACTION_FINDPROPSTRICT)
- /// + 0x66 (ABC_ACTION_GETPROPERTY)
+
+ /// 0x60 ABC_ACTION_GETLEX
+ /// Stream: V32 'name_id' (no ns expansion)
+ /// Stack Out:
+ /// property -- The result of 0x5D (ABC_ACTION_FINDPROPSTRICT)
+ /// + 0x66 (ABC_ACTION_GETPROPERTY)
case SWF::ABC_ACTION_GETLEX:
{
asName a = pool_name(mStream->read_V32(), mPoolObject);
as_value val = find_prop_strict(a);
- pop_stack();
-
- push_stack(val);
+ log_abc("GETLEX: found value %s", val);
+ mStack.top(0) = val;
break;
}
- /// ABC_ACTION_SETPROPERTY
- /// Stream: V32 'name_id'
- /// Stack In:
- /// value -- The value to be used
- /// [ns [n]] -- Namespace stuff
- /// OR
- /// [key] -- Key name for property. Will not have both Namespace
and key.
- /// obj -- The object whose property is to be set
- /// Stack Out:
- /// .
- /// NB: If the name at name_id is completely qualified, neither a
namespace
- /// nor a key is needed. If the name_id refers to a name with a
runtime
- /// namespace, then this will be used. If neither of those is
true and
- /// obj is a dictionary and key is a name, then the name_id is
discarded and
- /// key/value is set in the dictionary obj instead.
+ /// ABC_ACTION_SETPROPERTY
+ /// Stream: V32 'name_id'
+ /// Stack In:
+ /// value -- The value to be used
+ /// [ns [n]] -- Namespace stuff
+ /// OR
+ /// [key] -- Key name for property. Will not have both
+ /// Namespace and key.
+ /// obj -- The object whose property is to be set
+ /// Stack Out:
+ /// .
+ /// NB: If the name at name_id is completely qualified,
+ /// neither a namespace nor a key is needed. If the
+ /// name_id refers to a name with a runtime
+ /// namespace, then this will be used. If neither of
+ /// those is true and obj is a dictionary and key is
+ /// a name, then the name_id is discarded and key/value
+ /// is set in the dictionary obj instead.
case SWF::ABC_ACTION_SETPROPERTY:
{
as_value value = pop_stack();
@@ -1636,22 +1662,22 @@
string_table::key name = 0;
asName a = pool_name(mStream->read_V32(), mPoolObject);
- // TODO: If multiname is runtime we need to also pop
namespace
- // and name values of the stack.
+ // TODO: If multiname is runtime we need to also pop
+ // namespace and name values off the stack.
if (a.flags() == asName::KIND_MultinameL) {
+ log_abc("SETPROPERTY: name is a late runtime "
+ "multiname");
as_value nameValue = pop_stack();
name = mST.find(nameValue.to_string());
}
- else{
- name = a.getGlobalName();
- }
+ else name = a.getGlobalName();
as_value val = pop_stack();
as_object *object = val.to_object().get();
if (!object) {
- log_error("Expected object on stack, but none found
(%s)!",
- val);
+ log_error("ABC_ACTION_SETPROPERTY: expecting object "
+ "on stack, got %s!", val);
break;
}
@@ -1704,64 +1730,76 @@
print_scope_stack();
break;
}
- /// 0x66 ABC_ACTION_GETPROPERTY
- /// Stream: V32 'name_id'
- /// Stack In:
- /// [ns [n]] -- Namespace stuff
- /// OR
- /// [key] -- Key name for property. Will not have both Namespace
and key.
- /// obj -- The object whose property is to be retrieved
- /// Stack Out:
- /// prop -- The requested property.
- /// NB: See 0x61 (ABC_ACTION_SETPROPETY) for the decision of
ns/key.
+
+ /// 0x66 ABC_ACTION_GETPROPERTY
+ /// Stream: V32 'name_id'
+ /// Stack In:
+ /// [ns [n]] -- Namespace stuff
+ /// OR
+ /// [key] -- Key name for property. Will not have both
+ /// Namespace and key.
+ /// obj -- The object whose property is to be retrieved
+ /// Stack Out:
+ /// prop -- The requested property.
+ /// NB: See 0x61 (ABC_ACTION_SETPROPETY) for the decision of
+ /// ns/key.
case SWF::ABC_ACTION_GETPROPERTY:
{
+ string_table::key ns = 0;
+ string_table::key name = 0;
+ asName a = pool_name(mStream->read_V32(), mPoolObject);
+ // TODO: If multiname is runtime we need to also pop
+ // namespace and name values of the stack.
+ if (a.flags() == asName::KIND_MultinameL) {
+ as_value nameValue = pop_stack();
+ name = mST.find(nameValue.to_string());
+ }
+ else name = a.getGlobalName();
+
+ as_value object_val = pop_stack();
+ as_object* object = object_val.to_object().get();
+
+ if (!object) {
+ log_debug(_("ABC_ACTION_GETPROPERTY: expecting "
+ "object on stack, got %s."), object_val);
+ push_stack(as_value());
+ break;
+ }
+
as_value prop;
- string_table::key ns = 0;
- string_table::key name = 0;
- asName a = pool_name(mStream->read_V32(), mPoolObject);
- //TODO: If multiname is runtime we need to also pop
namespace and name values of the stack.
- if (a.flags() == asName::KIND_MultinameL) {
- as_value nameValue = pop_stack();
- name = mST.find(nameValue.to_string());
+
+ const bool found = object->get_member(name, &prop, ns);
+ if (!found) {
+ log_abc("GETPROPERTY: property %s not found",
+ mST.value(name));
}
else {
- name = a.getGlobalName();
- }
-
- as_value object_val = pop_stack();
-
- as_object* object = object_val.to_object().get();
- if (!object) {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("Can't get a property of a value that
doesn't "
- "cast to an object (%s)."), object_val);
- )
- }
- else{
- object->get_member(name, &prop, ns);
+ log_abc("GETPROPERTY: property %s is %s",
+ mST.value(name), prop);
}
push_stack(prop);
-
break;
}
- /// 0x68 ABC_ACTION_INITPROPERTY
- /// Stream V32 'name_id'
- /// Stack In:
- /// value -- The value to be put into the property.
- /// [ns [n]] -- Namespace stuff
- /// obj -- The object whose property is to be initialized
- /// Stack Out:
- /// .
- /// Do:
- /// Set obj::(resolve)'name_id' to value, set bindings from the
context.
+
+ /// 0x68 ABC_ACTION_INITPROPERTY
+ /// Stream V32 'name_id'
+ /// Stack In:
+ /// value -- The value to be put into the property.
+ /// [ns [n]] -- Namespace stuff
+ /// obj -- The object whose property is to be initialized
+ /// Stack Out:
+ /// .
+ /// Do:
+ /// Set obj::(resolve)'name_id' to value, set bindings
+ /// from the context.
case SWF::ABC_ACTION_INITPROPERTY:
{
boost::uint32_t index = mStream->read_V32();
asName a = pool_name(index, mPoolObject);
as_value v = pop_stack();
- //TODO: If multiname is a runtime mutiname we need to also
pop name and namespace values.
+ // TODO: If multiname is a runtime mutiname we need to also
+ // pop name and namespace values.
as_value object_val = pop_stack();
as_object* object = object_val.to_object().get();
@@ -2964,7 +3002,7 @@
std::auto_ptr<as_environment::ScopeStack> envStack ( getScopeStack() );
val = env.get_variable(path, *envStack, &target);
- push_stack(as_value(target));
+ push_stack(target);
mScopeStack.pop();
return val;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10928: Fix crash due to unchecked return from to_object().,
Benjamin Wolsey <=