2 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 // The AS3 abc block format reader.
21 #include "gnashconfig.h"
23 #include "SWFStream.h" // for use
26 #include "ClassHierarchy.h"
28 #include "namedStrings.h"
29 #include "CodeStream.h"
30 #include "action_buffer.h"
32 #include "Global_as.h"
34 #include <boost/bind.hpp>
41 Trait::finalize(AbcBlock
*block
, abc::Class
* script
, bool do_static
)
43 log_abc("Finalize class %s (%s), trait kind: %s",
44 block
->_stringTable
->value(script
->getName()), script
, _kind
);
54 log_abc("Trait type: %s",
56 block
->_multinamePool
[_typeIndex
].getABCName()]);
57 type
= block
->locateClass(block
->_multinamePool
[_typeIndex
]);
60 type
= block
->mTheObject
;
64 log_error(_("ABC: Finalizing trait yielded bad type for slot."));
68 // The name has been validated in read.
69 // TODO: Find a better way to initialize trait values.
75 log_abc("Adding property=%s with value=%s slot=%u",
76 block
->_stringPool
[_name
], _value
, _slotID
);
78 script
->addValue(_globalName
, _namespace
, _slotID
, type
,
79 _value
, _kind
== KIND_CONST
, do_static
);
84 script
->addMethod(_globalName
, _namespace
, _method
, false);
88 script
->addGetter(_name
, _namespace
, _method
, do_static
);
92 script
->addSetter(_name
, _namespace
, _method
, do_static
);
96 log_abc("Adding class %s, value %s, slot=%u",
97 block
->_stringPool
[_name
], _value
, _slotID
);
98 script
->addMemberScript(_globalName
, _namespace
, _slotID
,
99 block
->_classes
[_classInfoIndex
], do_static
);
103 script
->addSlotFunction(_name
, _namespace
, _slotID
, _method
,
114 Trait::finalize_mbody(AbcBlock
*block
, Method
*pMethod
)
116 log_abc("Finalizing method trait: kind %s", _kind
);
122 // Validate the type.
125 type
= block
->locateClass(block
->_multinamePool
[_typeIndex
]);
128 type
= block
->mTheObject
;
132 log_error(_("ABC: Finalizing trait yielded bad type for slot."));
136 // The name has been validated in read.
137 // TODO: Find a better way to initialize trait values.
139 _value
= as_value((as_object
*)0); // NULL value, right ?
141 log_abc("Adding property=%s with value=%s slot=%u",
142 block
->_stringPool
[_name
], _value
.toDebugString(), _slotID
);
143 pMethod
->addValue(_globalName
, _namespace
, _slotID
, type
,
144 _value
, _kind
== KIND_CONST
);
149 pMethod
->addMethod(_name
, _namespace
, _method
);
154 pMethod
->addGetter(_name
, _namespace
, _method
);
159 pMethod
->addSetter(_name
, _namespace
, _method
);
164 pMethod
->addMemberScript(_name
, _namespace
, _slotID
,
165 block
->_classes
[_classInfoIndex
]);
170 pMethod
->addSlotFunction(_name
, _namespace
, _slotID
, _method
);
174 // Not here -- validated already in read.
180 /// Read an AS3 'trait'
182 Trait::read(SWFStream
* in
, AbcBlock
*block
)
184 boost::uint32_t name
= in
->read_V32();
185 if (name
>= block
->_multinamePool
.size())
187 log_error(_("ABC: Bad name for trait."));
190 if (!block
->_multinamePool
[name
].isQName())
192 log_error(_("ABC: Trait name must be fully qualified."));
195 MultiName multiname
= block
->_multinamePool
[name
];
196 _name
= block
->_multinamePool
[name
].getABCName();
197 _globalName
= block
->_multinamePool
[name
].getGlobalName();
198 _namespace
= block
->_multinamePool
[name
].getNamespace();
200 boost::uint8_t kind
= in
->read_u8();
201 _kind
= static_cast<Kind
>(kind
& 0x0F);
203 log_abc("Trait name: %s, Trait kind: %s",
204 block
->_stringPool
[multiname
.getABCName()], _kind
);
211 _slotID
= in
->read_V32();
212 _typeIndex
= in
->read_V32();
213 boost::uint32_t vindex
= in
->read_V32();
214 log_abc("Slot ID=%u Type=%s Pool index=%u", _slotID
,
216 block
->_multinamePool
[_typeIndex
].getABCName()], vindex
);
219 const AbcBlock::PoolConstant c
=
220 static_cast<AbcBlock::PoolConstant
>(in
->read_u8());
222 if (!block
->pool_value(vindex
, c
, _value
))
223 return false; // Message done by pool_value
226 else _hasValue
= false;
233 // Ignore the 'disp_id'
236 boost::uint32_t offset
= in
->read_V32();
237 log_abc("Method index=%u", offset
);
238 if (offset
>= block
->_methods
.size()) {
239 log_error(_("Bad method id in trait."));
242 _method
= block
->_methods
[offset
];
247 _slotID
= in
->read_V32();
248 _classInfoIndex
= in
->read_V32();
249 log_abc("Slot id: %u Class index: %u Class Name: %s", _slotID
,
251 block
->_stringTable
->value(
252 block
->_classes
[_classInfoIndex
]->getName()));
254 if (_classInfoIndex
>= block
->_classes
.size()) {
255 log_error(_("Bad Class id in trait."));
262 _slotID
= in
->read_V32();
263 boost::uint32_t offset
= in
->read_V32();
264 if (offset
>= block
->_methods
.size()) {
265 log_error(_("Bad method id in trait."));
268 _method
= block
->_methods
[offset
];
273 log_error(_("ABC: Unknown type of trait."));
277 // Ignore the metadata, but it must be read to know how to ignore it.
278 if ((kind
>> 4) & 0x04) {
279 boost::uint32_t mcount
= in
->read_V32();
280 for (size_t i
= 0; i
< mcount
; ++i
) {
288 operator<<(std::ostream
& o
, const Trait::Kind k
)
291 case abc::Trait::KIND_SLOT
:
293 case abc::Trait::KIND_CONST
:
295 case abc::Trait::KIND_METHOD
:
296 return o
<< "method";
297 case abc::Trait::KIND_GETTER
:
298 return o
<< "getter";
299 case abc::Trait::KIND_SETTER
:
300 return o
<< "setter";
301 case abc::Trait::KIND_CLASS
:
303 case abc::Trait::KIND_FUNCTION
:
304 return o
<< "function";
306 return o
<< "Unknown kind " << static_cast<int>(k
);
312 _stringTable(&VM::get().getStringTable())
314 mCH
= &VM::get().getMachine()->global()->classHierarchy();
315 // TODO: Make this the real 'Object' prototype.
316 mCH
->getGlobalNs()->stubPrototype(*mCH
, NSV::CLASS_OBJECT
);
317 mTheObject
= mCH
->getGlobalNs()->getScript(NSV::CLASS_OBJECT
);
321 AbcBlock::prepare(Machine
* mach
)
324 std::for_each(_classes
.begin(), _classes
.end(),
325 std::mem_fun(&abc::Class::initPrototype
));
326 // The last (entry) script has Global as its prototype.
327 // This can be deduced because the global classes are initialized with a
328 // slot on script 0 (entry script). OpNewClass then attempts to set the
329 // corresponding slot once the class has been constructed. At this point,
330 // global should verifiably be on the stack, so the slots are expected
331 // to be set on the global object.
332 // It seems likely, though testing it is not straightforward, that all
333 // scripts have Global as a target object (prototype), so for now we
335 std::for_each(_scripts
.begin(), _scripts
.end(),
336 boost::bind(&abc::Class::setPrototype
, _1
, mach
->global()));
338 std::for_each(_methods
.begin(), _methods
.end(),
339 boost::bind(&Method::initPrototype
, _1
, mach
));
341 // TODO: Remove this, initialize traits only when needed; possibly
342 // consruct them on parsing without the need for a finalize method.
343 std::for_each(_methods
.begin(), _methods
.end(),
344 boost::bind(&abc::Method::initTraits
, _1
, *this));
345 std::for_each(_classes
.begin(), _classes
.end(),
346 boost::bind(&abc::Class::initTraits
, _1
, *this));
347 std::for_each(_scripts
.begin(), _scripts
.end(),
348 boost::bind(&abc::Class::initTraits
, _1
, *this));
353 AbcBlock::check_multiname_name(boost::uint32_t name
)
356 if (name
>= _stringPool
.size()) {
357 throw ParserException("ABC: Out of bounds string for Multiname.");
362 AbcBlock::check_multiname_namespace(boost::uint32_t ns
)
364 if (ns
>= _namespacePool
.size()) {
365 throw ParserException("ABC: Out of bounds namespace for Multiname.");
370 AbcBlock::check_multiname_namespaceset(boost::uint32_t nsset
)
374 throw ParserException("ABC: 0 selection for namespace set is invalid.");
376 if (nsset
>= _namespaceSetPool
.size())
378 throw ParserException("ABC: Out of bounds namespace set for Multiname.");
383 AbcBlock::setMultinameNames(MultiName
*n
, abc::URI ABCName
)
386 n
->setABCName(ABCName
);
387 std::string name
= _stringPool
[ABCName
];
388 string_table::key global_key
= _stringTable
->find(name
, true);
389 log_abc("Global key %u", global_key
);
390 n
->setGlobalName(global_key
);
391 log_abc("Multiname: %s ABCName set to %u, global name set to %u",
392 name
, n
->getABCName(), n
->getGlobalName());
396 AbcBlock::setNamespaceURI(Namespace
*ns
, abc::URI ABCName
)
398 std::string name
= _stringPool
[ABCName
];
399 string_table::key global_key
= _stringTable
->find(name
);
400 ns
->setURI(global_key
);
401 log_abc("Namespace: %s AbcURI=%u URI=%u.", name
, ABCName
, global_key
);
405 AbcBlock::locateClass(const std::string
& className
)
408 const std::string::size_type pos
= className
.rfind(".");
412 const std::string
& nsstr
= (pos
!= std::string::npos
) ?
413 className
.substr(0, pos
) : "";
415 const std::string
& clstr
= (pos
!= std::string::npos
) ?
416 className
.substr(pos
+ 1) : className
;
418 a
.setGlobalName(_stringTable
->find(clstr
));
420 for (std::vector
<Namespace
*>::iterator i
= _namespacePool
.begin();
421 i
!= _namespacePool
.end(); ++i
) {
423 const size_t key
= (*i
)->getURI();
425 if (key
== _stringTable
->find(nsstr
)) {
431 return locateClass(a
);
436 AbcBlock::locateClass(MultiName
& m
)
438 abc::Class
* found
= 0;
440 if (m
.getNamespace())
442 found
= m
.getNamespace()->getScript(m
.getGlobalName());
443 if (found
) return found
;
445 if (m
.namespaceSet() && !m
.namespaceSet()->empty())
447 std::vector
<Namespace
*>::const_iterator i
;
448 for (i
= m
.namespaceSet()->begin(); i
!= m
.namespaceSet()->end(); ++i
) {
450 found
= (*i
)->getScript(m
.getGlobalName());
451 if (found
) return found
;
455 log_abc("Could not locate class in ABC block resources!");
461 /// Read the ActionBlock version number.
463 AbcBlock::read_version()
465 // Minor version, major version.
466 mVersion
= (_stream
->read_u16()) | (_stream
->read_u16() << 16);
467 log_debug(_("Abc Version: %d.%d"), (mVersion
& 0xFFFF0000) >> 16,
468 (mVersion
& 0x0000FFFF));
472 /// Read the pool of integer constants.
474 AbcBlock::read_integer_constants()
476 // count overestimates by 1.
477 boost::uint32_t count
= _stream
->read_V32();
478 _integerPool
.resize(count
);
481 for (unsigned int i
= 1; i
< count
; ++i
)
483 _integerPool
[i
] = static_cast<boost::int32_t> (_stream
->read_V32());
488 /// Read the pool of unsigned integer constants.
490 AbcBlock::read_unsigned_integer_constants()
492 // count overestimates by 1.
493 boost::uint32_t count
= _stream
->read_V32();
494 _uIntegerPool
.resize(count
);
496 _uIntegerPool
[0] = 0;
497 for (unsigned int i
= 1; i
< count
; ++i
)
499 _uIntegerPool
[i
] = _stream
->read_V32();
504 /// Read the pool of 64-bit double constants.
506 AbcBlock::read_double_constants()
508 boost::uint32_t count
= _stream
->read_V32();
509 _doublePool
.resize(count
);
510 if (count
) _doublePool
[0] = 0.0;
512 for (size_t i
= 1; i
< count
; ++i
)
514 _doublePool
[i
] = _stream
->read_d64();
515 log_abc("Double %u=%lf", i
, _doublePool
[i
]);
520 /// Read the pool of string constants.
522 AbcBlock::read_string_constants()
524 log_abc("Begin reading string constants.");
525 boost::uint32_t count
= _stream
->read_V32();
526 log_abc("There are %u string constants.", count
);
527 _stringPool
.resize(count
);
533 for (size_t i
= 1; i
< count
; ++i
) {
534 boost::uint32_t length
= _stream
->read_V32();
535 _stream
->read_string_with_length(length
, _stringPool
[i
]);
536 log_abc("Adding string constant to string pool: index=%u %s",
542 /// Read the pool of namespaces
543 /// Any two namespaces with the same uri here are the same namespace,
544 /// excepting private namespaces.
546 AbcBlock::read_namespaces()
548 log_abc("Begin reading namespaces.");
549 boost::uint32_t count
= _stream
->read_V32();
550 log_abc("There are %u namespaces.", count
);
551 _namespacePool
.resize(count
);
553 _namespacePool
[0] = mCH
->getGlobalNs();
556 for (size_t i
= 1; i
< count
; ++i
)
558 NamespaceConstant kind
=
559 static_cast<NamespaceConstant
>(_stream
->read_u8());
561 boost::uint32_t nameIndex
= _stream
->read_V32();
562 log_abc("Namespace %u: %s, index %u, name %s", i
, kind
,
563 nameIndex
, _stringPool
[nameIndex
]);
565 if (nameIndex
>= _stringPool
.size()) {
566 log_error(_("ABC: Bad string given for namespace."));
570 if (kind
== PRIVATE_NS
)
572 _namespacePool
[i
] = mCH
->anonNamespace(nameIndex
);
573 _namespacePool
[i
]->setPrivate();
577 string_table::key gn
= _stringTable
->find(_stringPool
[nameIndex
]);
578 Namespace
*n
= mCH
->findNamespace(gn
);
579 if (!n
) n
= mCH
->addNamespace(gn
);
580 _namespacePool
[i
] = n
;
582 if (kind
== PROTECTED_NS
) _namespacePool
[i
]->setProtected();
583 if (kind
== PACKAGE_NS
) _namespacePool
[i
]->setPackage();
584 setNamespaceURI(_namespacePool
[i
], nameIndex
);
589 /// Read the set of sets of namespaces.
591 AbcBlock::read_namespace_sets()
593 boost::uint32_t count
= _stream
->read_V32();
594 _namespaceSetPool
.resize(count
);
597 _namespaceSetPool
[0].resize(0);
599 for (unsigned int i
= 1; i
< count
; ++i
)
601 boost::uint32_t icount
= _stream
->read_V32();
602 _namespaceSetPool
[i
].resize(icount
);
603 for (unsigned int j
= 0; j
< icount
; ++j
)
605 boost::uint32_t selection
= _stream
->read_V32();
606 if (!selection
|| selection
>= _namespacePool
.size())
608 log_error(_("ABC: Bad namespace for namespace set."));
611 _namespaceSetPool
[i
][j
] = _namespacePool
[selection
];
617 /// Read the multinames.
619 AbcBlock::read_multinames()
621 boost::uint32_t count
= _stream
->read_V32();
622 log_abc("There are %u multinames.", count
);
623 _multinamePool
.resize(count
);
626 // _multinamePool[0].setABCName(0);
627 setMultinameNames(&_multinamePool
[0], 0);
628 _multinamePool
[0].setNamespace(mCH
->getGlobalNs());
630 for (unsigned int i
= 1; i
< count
; ++i
)
632 MultiName::Kind kind
= static_cast<MultiName::Kind
>(_stream
->read_u8());
633 boost::uint32_t ns
= 0;
634 boost::uint32_t name
= 0;
635 boost::uint32_t nsset
= 0;
637 log_abc("Multiname %u has kind %s", i
, static_cast<int>(kind
));
639 // Read, but don't upper validate until after the switch.
642 case MultiName::KIND_Qname
:
643 case MultiName::KIND_QnameA
:
644 ns
= _stream
->read_V32();
645 check_multiname_namespace(ns
);
646 name
= _stream
->read_V32();
647 check_multiname_name(name
);
648 log_abc("\tnamespace_index=%u name_index=%u name=%s",
649 ns
, name
, _stringPool
[name
]);
652 case MultiName::KIND_RTQname
:
653 case MultiName::KIND_RTQnameA
:
654 name
= _stream
->read_V32();
655 check_multiname_name(name
);
658 case MultiName::KIND_RTQnameL
:
659 case MultiName::KIND_RTQnameLA
:
662 case MultiName::KIND_Multiname
:
663 case MultiName::KIND_MultinameA
:
664 name
= _stream
->read_V32();
665 check_multiname_name(name
);
666 nsset
= _stream
->read_V32();
667 check_multiname_namespaceset(nsset
);
670 case MultiName::KIND_MultinameL
:
671 case MultiName::KIND_MultinameLA
:
672 nsset
= _stream
->read_V32();
673 check_multiname_namespaceset(nsset
);
678 log_error(_("Action Block: Unknown multiname type (%d)."),
683 _multinamePool
[i
].setFlags(kind
);
684 setMultinameNames(&_multinamePool
[i
], name
);
685 log_abc("Done setting multinames: abc=%u global=%u",
686 _multinamePool
[i
].getABCName(),
687 _multinamePool
[i
].getGlobalName());
689 _multinamePool
[i
].setNamespace(_namespacePool
[ns
]);
692 _multinamePool
[i
].namespaceSet(&_namespaceSetPool
[nsset
]);
694 } // End of main loop.
699 AbcBlock::pool_value(boost::uint32_t index
, PoolConstant type
, as_value
&v
)
704 log_abc("Pool value: index is %u type is 0x%X", index
, type
| 0x0);
709 if (index
>= _stringPool
.size())
711 log_error(_("Action Block: Bad index in optional argument."));
714 v
.set_string(_stringPool
[index
]);
719 if (index
>= _integerPool
.size())
721 log_error(_("Action Block: Bad index in optional argument."));
724 v
.set_double(_integerPool
[index
]);
729 if (index
>= _uIntegerPool
.size())
731 log_error(_("Action Block: Bad index in optional argument."));
734 v
.set_double(_uIntegerPool
[index
]);
739 if (index
>= _doublePool
.size())
741 log_error(_("Action Block: Bad index in optional argument."));
744 v
.set_double(static_cast<double>(_doublePool
[index
]));
747 case POOL_NAMESPACE
: // Namespace
749 if (index
>= _namespacePool
.size())
751 log_error(_("ABC: Bad index in optional argument, namespaces."));
756 case POOL_FALSE
: // False value
761 case POOL_TRUE
: // True value
766 case POOL_NULL
: // NULL value
771 default: // All others are bogus.
773 log_error(_("ABC: Bad default value type (%X), but continuing."), type
);
781 /// Read the method infos.
783 AbcBlock::read_method_infos()
785 log_abc("Begin read_method_infos.");
787 boost::uint32_t count
= _stream
->read_V32();
788 log_abc("Method count: %u", count
);
790 _methods
.resize(count
);
791 for (unsigned int i
= 0; i
< count
; ++i
)
793 log_abc(" Reading method %u", i
);
794 Method
*pMethod
= mCH
->newMethod();
795 pMethod
->setMethodID(i
);
796 _methods
[i
] = pMethod
;
797 boost::uint32_t param_count
= _stream
->read_V32();
798 boost::uint32_t return_type
= _stream
->read_V32();
800 const std::string
& rt
= return_type
?
801 _stringPool
[_multinamePool
[return_type
].getABCName()] :
804 log_abc(" Param count: %u, return type: %s", param_count
,
807 pMethod
->setMinArgumentCount(param_count
);
808 pMethod
->setMaxArgumentCount(param_count
);
810 if (return_type
>= _multinamePool
.size()) {
811 log_error(_("ABC: Bad return type for method info."));
816 pMethod
->setReturnType(0);
819 // TODO: this can be 'void', which clearly isn't a class, so this
820 // seems bogus. As setReturnType is a no-op, we should log it
822 abc::Class
* rtScript
= locateClass(_multinamePool
[return_type
]);
824 log_abc(_("ABC: Unknown return type."));
827 pMethod
->setReturnType(rtScript
);
829 for (size_t j
= 0; j
< param_count
; ++j
) {
830 log_abc(" Reading parameter %u", j
);
831 // The parameter type.
832 boost::uint32_t ptype
= _stream
->read_V32();
834 const std::string
& pt
= return_type
?
835 _stringPool
[_multinamePool
[ptype
].getABCName()] :
838 log_abc(" Parameter type(index): %s(%u)", pt
, ptype
);
840 if (ptype
>= _multinamePool
.size()) {
841 log_error(_("ABC: Bad parameter type in method."));
845 // A value of 0 is legitimate, meaning 'any (*)'.
847 abc::Class
* param_type
= locateClass(_multinamePool
[ptype
]);
850 log_abc((_("ABC: Unknown parameter type.")));
853 // This currently also pushes 0, meaning 'any'; perhaps it
854 // should throw a VerifyError if the class is not known.
855 pMethod
->pushArgument(param_type
);
858 pMethod
->pushArgument(0);
862 boost::uint32_t method_name
= _stream
->read_V32();
863 log_abc( "Method name=%s %d", _stringPool
[method_name
], method_name
);
864 boost::uint8_t flags
= _stream
->read_u8();
865 log_abc(" Flags: %X", flags
| 0x0);
866 // log_abc("Check if flags and optional args.");
867 // If there are default parameters, read them now.
868 // Runtime will do validation of whether or not these can actually
869 // be assigned to the corresponding parameters.
870 if (flags
& METHOD_OPTIONAL_ARGS
) {
872 boost::uint32_t ocount
= _stream
->read_V32();
873 log_abc(" Optional args: %u", ocount
);
874 pMethod
->setMinArgumentCount(pMethod
->maxArgumentCount() - ocount
);
876 for (unsigned int j
= 0; j
< ocount
; ++j
) {
877 log_abc(" Reading optional arg: %u", j
);
878 boost::uint32_t index
= _stream
->read_V32();
880 PoolConstant kindof
=
881 static_cast<PoolConstant
>(_stream
->read_u8());
883 log_abc(" Index: %u Kindof: %u", index
, kindof
);
885 if (!pool_value(index
, kindof
, v
)) {
888 pMethod
->pushOptional(v
);
890 log_abc("Done handling optional args.");
893 if (flags
& METHOD_ACTIVATION
) {
894 log_abc("Method needs activation");
895 pMethod
->setNeedsActivation();
898 // If there are names present for the parameters, skip them.
899 if (flags
& METHOD_ARG_NAMES
) {
900 for (size_t j
= 0; j
< param_count
; ++j
) {
904 } // End of method loop.
908 /// Skip the metadata, which is useless to us.
910 AbcBlock::skip_metadata()
912 boost::uint32_t count
= _stream
->read_V32();
913 for (unsigned int i
= 0; i
< count
; ++i
)
915 _stream
->skip_V32(); // A name index.
916 boost::uint32_t icount
= _stream
->read_V32();
917 for (unsigned int j
= 0; j
< icount
; ++j
)
919 // key/values may not be stored together, but this still works.
927 /// Load the instances from the block.
929 AbcBlock::read_instances()
931 boost::uint32_t count
= _stream
->read_V32();
932 log_abc("There are %u instances.", count
);
933 _classes
.resize(count
);
934 for (size_t i
= 0; i
< count
; ++i
) {
935 //Read multiname index.
936 boost::uint32_t index
= _stream
->read_V32();
937 // 0 is allowed as a name, typically for the last entry.
938 if (index
>= _multinamePool
.size()) {
939 log_error(_("ABC: Out of bounds instance name."));
943 MultiName
& multiname
= _multinamePool
[index
];
945 // This must be a QName.
946 if (!multiname
.isQName()) {
947 log_error(_("ABC: QName required for instance."));
951 if (!multiname
.getNamespace()) {
952 log_error(_("ABC: No namespace to use for storing class."));
956 abc::Class
* cl
= locateClass(multiname
);
960 const string_table::key className
= multiname
.getGlobalName();
962 cl
= mCH
->newClass();
963 cl
->setName(className
);
965 if (!multiname
.getNamespace()->addScript(className
, cl
)) {
967 log_error(_("Duplicate class registration."));
970 log_debug("Adding class %s (%s) to namespace %s",
971 _stringTable
->value(multiname
.getGlobalName()),
972 _stringPool
[multiname
.getABCName()],
973 _stringTable
->value(multiname
.getNamespace()->getURI()));
974 log_debug("Namespace now:");
975 multiname
.getNamespace()->dump(*_stringTable
);
980 boost::uint32_t super_index
= _stream
->read_V32();
982 if (super_index
&& super_index
>= _multinamePool
.size()) {
983 log_error(_("ABC: Bad super type."));
988 cl
->setSuper(mTheObject
);
991 abc::Class
*pSuper
= locateClass(_multinamePool
[super_index
]);
994 log_error(_("ABC: Super type not found (%s)"),
995 _stringPool
[_multinamePool
[super_index
].getABCName()]);
999 if (pSuper
->isFinal())
1001 log_error(_("ABC: Can't extend a class which is final."));
1005 if (pSuper
->isInterface())
1007 log_error(_("ABC: Can't extend an interface type."));
1013 log_error(_("ABC: Class cannot be its own supertype."));
1016 cl
->setSuper(pSuper
);
1017 pSuper
->setInherited();
1020 boost::uint8_t flags
= _stream
->read_u8();
1021 log_abc("Instance %u(%s) multiname index=%u name=%s super index=%u "
1022 "flags=%X", i
, cl
, index
,
1023 _stringPool
[_multinamePool
[index
].getABCName()],
1024 super_index
, flags
| 0x0);
1026 if (flags
& INSTANCE_SEALED
) cl
->setSealed();
1027 if (flags
& INSTANCE_FINAL
) cl
->setFinal();
1028 if (flags
& INSTANCE_INTERFACE
) cl
->setInterface();
1029 if ((flags
& 7) == INSTANCE_DYNAMIC
) cl
->setDynamic();
1031 if (flags
& INSTANCE_PROTECTED_NS
) {
1032 boost::uint32_t ns_index
= _stream
->read_V32();
1033 if (ns_index
>= _namespacePool
.size()) {
1034 log_error(_("ABC: Bad namespace for protected."));
1037 // Set the protected namespace's parent, if it exists.
1038 if (cl
->getSuper()->hasProtectedNs())
1039 _namespacePool
[ns_index
]->setParent(
1040 cl
->getSuper()->getProtectedNs());
1041 cl
->setProtectedNs(_namespacePool
[ns_index
]);
1044 // This is the list of interfaces which the instances has agreed to
1045 // implement. They must be interfaces, and they must exist.
1046 boost::uint32_t intcount
= _stream
->read_V32();
1047 log_abc("This instance has %u interfaces.", intcount
);
1048 for (size_t j
= 0; j
< intcount
; ++j
) {
1049 boost::uint32_t i_index
= _stream
->read_V32();
1050 log_abc("Interface %u has multiname index=%u", i
, i_index
);
1051 // 0 is allowed as an interface, typically for the last one.
1052 if (i_index
>= _multinamePool
.size()) {
1053 log_error(_("ABC: Bad name for interface."));
1056 abc::Class
*pInterface
= locateClass(_multinamePool
[i_index
]);
1057 // These may be undefined still, so don't check interface just yet.
1058 if (0) //!pInterface || !pInterface->isInterface())
1060 log_error(_("ABC: Can't implement a non-interface type."));
1063 cl
->pushInterface(pInterface
);
1066 // The next thing should be the constructor.
1067 // TODO: What does this mean exactly? How does it differ from the one in
1068 // the class info block?
1069 boost::uint32_t offset
= _stream
->read_V32();
1070 log_abc("Moffset: %u", offset
);
1071 if (offset
>= _methods
.size()) {
1072 log_error(_("ABC: Out of bounds method for initializer."));
1075 // Don't validate for previous owner.
1076 cl
->setConstructor(_methods
[offset
]);
1078 // Next come the 'traits' of the instance. (The members.)
1079 boost::uint32_t tcount
= _stream
->read_V32();
1080 log_abc("Trait count: %u", tcount
);
1081 for (unsigned int j
= 0; j
< tcount
; ++j
)
1084 t
.set_target(cl
, false);
1085 if (!t
.read(_stream
, this)) return false;
1086 cl
->addInstanceTrait(t
);
1092 /// Read the class data
1094 AbcBlock::read_classes()
1096 // Count was found in read_instances().
1097 log_abc("Begin reading classes.");
1098 boost::uint32_t count
= _classes
.size();
1099 log_abc("There are %u classes.", count
);
1101 for (size_t i
= 0; i
< count
; ++i
) {
1102 abc::Class
* cl
= _classes
[i
];
1103 boost::uint32_t offset
= _stream
->read_V32();
1104 log_abc("Class %u(%s) static constructor index=%u", i
, cl
, offset
);
1106 if (offset
>= _methods
.size()) {
1107 log_error(_("ABC: Out of bound static constructor for class."));
1111 // Don't validate for previous owner.
1112 cl
->setStaticConstructor(_methods
[offset
]);
1114 boost::uint32_t tcount
= _stream
->read_V32();
1115 log_abc("This class has %u traits.", tcount
);
1116 for (size_t j
= 0; j
< tcount
; ++j
) {
1118 t
.set_target(cl
, true);
1119 if (!(t
.read(_stream
, this))) return false;
1120 cl
->addStaticTrait(t
);
1126 /// Read the scripts (global functions)
1127 /// The final script is the entry point for the block.
1129 AbcBlock::read_scripts()
1131 log_abc("Begin reading scripts.");
1133 const boost::uint32_t scriptcount
= _stream
->read_V32();
1134 log_abc("There are %u scripts.", scriptcount
);
1136 _scripts
.resize(scriptcount
);
1137 for (size_t i
= 0; i
< scriptcount
; ++i
) {
1139 abc::Class
* script
= mCH
->newClass();
1140 _scripts
[i
] = script
;
1142 boost::uint32_t offset
= _stream
->read_V32();
1143 log_abc("Reading script %u(%s) initializer method index=%u", i
,
1145 if (offset
>= _methods
.size()) {
1146 log_error(_("ABC: Out of bounds method for script."));
1150 script
->setConstructor(_methods
[offset
]);
1152 const boost::uint32_t tcount
= _stream
->read_V32();
1153 for (size_t j
= 0; j
< tcount
; ++j
) {
1156 t
.set_target(script
, false);
1157 if (!(t
.read(_stream
, this))) {
1160 log_abc("Trait: %u name: %s(%u) kind: %s value: %s ", j
,
1161 _stringPool
[t
._name
], t
._name
, t
._kind
, t
._value
);
1163 // TODO: this should not use Class!
1164 script
->addStaticTrait(t
);
1170 /// Read the method bodies and attach them to the methods.
1172 AbcBlock::read_method_bodies()
1174 boost::uint32_t count
= _stream
->read_V32();
1175 log_abc("There are %u method bodies.", count
);
1176 for (unsigned int i
= 0; i
< count
; ++i
)
1178 boost::uint32_t offset
= _stream
->read_V32();
1179 log_abc("Method body %u method offset=%u", i
, offset
);
1181 if (offset
>= _methods
.size()) {
1182 log_error(_("ABC: Out of bounds for method body."));
1186 Method
& method
= *_methods
[offset
];
1188 if (method
.getBody()) {
1189 log_error(_("ABC: Only one body per method."));
1193 // Maximum stack size.
1194 method
.setMaxStack(_stream
->read_V32());
1196 // Maximum register size.
1197 method
.setMaxRegisters(_stream
->read_V32());
1200 method
.setScopeDepth(_stream
->read_V32());
1203 method
.setMaxScope(_stream
->read_V32());
1206 boost::uint32_t clength
= _stream
->read_V32();
1207 method
.setBodyLength(clength
);
1210 //TODO: Clean this up.
1212 _stream
->read_string_with_length(clength
, body
);
1214 method
.setBody(new CodeStream(body
));
1216 // Exception count and exceptions
1218 // Note: catch type and variable name are documented to be
1219 // indices in the string pool, but they are in fact indices
1220 // in the multiname pool.
1221 const boost::uint32_t ecount
= _stream
->read_V32();
1222 for (unsigned int j
= 0; j
< ecount
; ++j
) {
1223 asException
*ex
= mCH
->newException();
1225 // Where the try block begins and ends.
1226 ex
->setStart(_stream
->read_V32());
1227 ex
->setEnd(_stream
->read_V32());
1229 // Where to go when the exception is activated.
1230 ex
->setCatch(_stream
->read_V32());
1232 // What types should be caught.
1233 boost::uint32_t catch_type
= _stream
->read_V32();
1234 if (catch_type
>= _multinamePool
.size()) {
1235 log_error(_("ABC: Out of bound type for exception."));
1242 abc::Class
*type
= locateClass(_multinamePool
[catch_type
]);
1245 log_error(_("ABC: Unknown type of object to catch. (%s)"),
1246 _stringTable
->value(
1247 _multinamePool
[catch_type
].getABCName()));
1250 // Fake it, for now:
1254 ex
->setCatchType(type
);
1258 // A variable name for the catch type.
1259 // In version 46.15, no names.
1260 if (mVersion
!= ((46 << 16) | 15)) {
1261 boost::uint32_t cvn
= _stream
->read_V32();
1262 if (cvn
>= _multinamePool
.size()) {
1263 log_error(_("ABC: Out of bound name for caught "
1267 ex
->setName(_multinamePool
[cvn
].getABCName());
1268 ex
->setNamespace(_multinamePool
[cvn
].getNamespace());
1273 boost::uint32_t tcount
= _stream
->read_V32();
1274 for (unsigned int j
= 0; j
< tcount
; ++j
)
1277 t
.set_target(_methods
[offset
]);
1279 if (!t
.read(_stream
, this)) {
1283 log_abc("Activation trait: %u name: %s, kind: %s, value: %s ", j
,
1284 _stringPool
[t
._name
], t
._kind
, t
._value
);
1285 _methods
[offset
]->addTrait(t
);
1291 // Load up all of the data.
1293 AbcBlock::read(SWFStream
& in
)
1295 // This isn't very nice:
1298 if (!read_version()) return false;
1299 if (!read_integer_constants()) return false;
1300 if (!read_unsigned_integer_constants()) return false;
1301 log_abc("Done reading unsigned integer constants.");
1303 if (!read_double_constants()) return false;
1304 log_abc("Done reading double constants.");
1306 if (!read_string_constants()) return false;
1307 log_abc("Done reading string constants.");
1309 if (!read_namespaces()) return false;
1310 log_abc("Done reading namespaces.");
1312 if (!read_namespace_sets()) return false;
1313 log_abc("Done reading namespace sets.");
1315 if (!read_multinames()) return false;
1316 log_abc("Done reading multinames.");
1318 if (!read_method_infos()) return false;
1319 log_abc("Done reading method infos.");
1321 if (!skip_metadata()) return false;
1322 log_abc("Done reading metadata.");
1324 if (!read_instances()) return false;
1325 log_abc("Done reading instances.");
1327 if (!read_classes()) return false;
1328 log_abc("Done reading classes.");
1330 if (!read_scripts()) return false;
1331 log_abc("Done reading scripts.");
1333 if (!read_method_bodies()) return false;
1334 log_abc("Done reading stuff.");
1336 for (size_t i
=0; i
< _methods
.size(); ++i
) {
1337 log_abc("Method %d body:", i
);
1338 IF_VERBOSE_PARSE(_methods
[i
]->print_body());
1345 AbcBlock::update_global_name(unsigned int multiname_index
)
1348 MultiName
* multiname
= &_multinamePool
[multiname_index
];
1349 string_table::key new_key
=
1350 _stringTable
->find(_stringPool
[multiname
->getABCName()], false);
1351 multiname
->setGlobalName(new_key
);
1355 operator<<(std::ostream
& o
, AbcBlock::NamespaceConstant c
)
1359 case AbcBlock::PRIVATE_NS
:
1360 return o
<< "private namespace";
1361 case AbcBlock::CONSTANT_NS
:
1362 return o
<< "constant namespace";
1363 case AbcBlock::PACKAGE_NS
:
1364 return o
<< "package namespace";
1365 case AbcBlock::PACKAGE_INTERNAL_NS
:
1366 return o
<< "package internal namespace";
1367 case AbcBlock::PROTECTED_NS
:
1368 return o
<< "protected namespace";
1369 case AbcBlock::EXPLICIT_NS
:
1370 return o
<< "explicit namespace";
1371 case AbcBlock::STATIC_PROTECTED_NS
:
1372 return o
<< "static protected namespace";
1374 return o
<< "invalid namespace constant";
1379 operator<<(std::ostream
& o
, AbcBlock::MethodConstant c
)
1383 case AbcBlock::METHOD_ARGS
:
1384 return o
<< "method arg";
1385 case AbcBlock::METHOD_ACTIVATION
:
1386 return o
<< "method activation";
1387 case AbcBlock::METHOD_MORE
:
1388 return o
<< "method more";
1389 case AbcBlock::METHOD_OPTIONAL_ARGS
:
1390 return o
<< "method optional args";
1391 case AbcBlock::METHOD_IGNORE
:
1392 return o
<< "method ignore";
1393 case AbcBlock::METHOD_NATIVE
:
1394 return o
<< "method native";
1395 case AbcBlock::METHOD_DEFAULT_NS
:
1396 return o
<< "default namespace";
1397 case AbcBlock::METHOD_ARG_NAMES
:
1398 return o
<< "method arg names";
1400 return o
<< "invalid method constant";
1405 operator<<(std::ostream
& o
, AbcBlock::InstanceConstant c
)
1409 case AbcBlock::INSTANCE_SEALED
:
1410 return o
<< "instance sealed";
1411 case AbcBlock::INSTANCE_FINAL
:
1412 return o
<< "instance final";
1413 case AbcBlock::INSTANCE_INTERFACE
:
1414 return o
<< "instance interface";
1415 case AbcBlock::INSTANCE_DYNAMIC
:
1416 return o
<< "instance dynamic";
1417 case AbcBlock::INSTANCE_PROTECTED_NS
:
1418 return o
<< "instance protected namespace";
1420 return o
<< "invalid instance constant";
1425 operator<<(std::ostream
& o
, AbcBlock::PoolConstant c
)
1429 case AbcBlock::POOL_STRING
:
1430 return o
<< "pool string";
1431 case AbcBlock::POOL_INTEGER
:
1432 return o
<< "pool integer";
1433 case AbcBlock::POOL_UINTEGER
:
1434 return o
<< "pool uinteger";
1435 case AbcBlock::POOL_DOUBLE
:
1436 return o
<< "pool double";
1437 case AbcBlock::POOL_NAMESPACE
:
1438 return o
<< "pool namespace";
1439 case AbcBlock::POOL_FALSE
:
1440 return o
<< "pool false";
1441 case AbcBlock::POOL_TRUE
:
1442 return o
<< "pool true";
1443 case AbcBlock::POOL_NULL
:
1444 return o
<< "pool null";
1446 return o
<< "invalid pool constant";
1452 } // namespace gnash