Commit Graph

291 Commits

Author SHA1 Message Date
Mike Welsh d9e7a6a960 avm1: Implement Boolean class 2020-01-21 18:24:49 -08:00
Mike Welsh e71099edd5 tests: Add primitive_type_globals test 2020-01-21 18:24:49 -08:00
Mike Welsh 8263d13fd0 avm1: Implement Number class 2020-01-21 18:24:49 -08:00
Mike Welsh b49357e46f avm1: Boxing a value calls the object constructor 2020-01-21 18:24:49 -08:00
Mike Welsh ccf62979a1 avm1: Implement String methods 2020-01-21 18:24:49 -08:00
David Wendt 2f9d50cdb8 Very rudimentary/basic/not-good implementation of `String`, plus auto-boxing for primitive strings getting their methods taken. 2020-01-21 18:24:49 -08:00
David Wendt 4d1e49882b Add another object class for boxed primitive values, because the language demands it. 2020-01-21 18:24:49 -08:00
Mike Welsh 13b4cd4c1b avm1: Add Value::coerce_to_i32/u32/u16 methods
Add these methods that will explicilty coerce a value to an int,
following the wrapping behavior in the ECMAScript specs (ToInt32,
ToUInt32, ToUInt16).

This also fixed an off-by-one error for negative numbers in the
previous implementation.

These will call `valueOf` if necessary. AVM code that requires an
integer will probably use one of these (`coerce_to_i32` usually).
2020-01-20 13:28:27 -08:00
Nathan Adams 4ad6ef8b83 core: Implemented Key.getCode() 2020-01-17 15:11:38 -08:00
Nathan Adams adceceed5d avm1: Removed redundant double registration of Key 2020-01-17 15:11:38 -08:00
Nathan Adams cef7d3eba2 avm1: Implement Key constants 2020-01-17 15:11:38 -08:00
Nathan Adams fdf1d38d21 avm1: Implement remainder of Math 2020-01-13 15:57:56 -08:00
Mike Welsh 001a931afe avm1: Avm1::pop should always succeed
Don't return a Result from `pop`. Instead, emit a warning and
return Undefined if there is an underflow.
2020-01-07 15:59:14 -08:00
Mike Welsh a28e97d8c3 avm1: Don't push returns from non-function stack frames 2020-01-06 20:49:05 -08:00
Mike Welsh 7e05da6147 avm1: Fix issues with traversing the scope chain in SetVariable
When setting a variable in a function-local scope, if that variable
has not been defined in the function scope, it should be defined in
the executing movieclip's scope. Previously it would get defined
in the function's scope. Changed Scope::overwrite to Scope::set,
and modified the behavior to stop traversing and define the value
when it hits a movie clip Target scope.

Also, modified With scopes to properly add onto the end of the scope
chain.
2020-01-06 20:49:05 -08:00
David Wendt f8b5b8a032 Use `unwrap_or_default` where available 2020-01-05 00:22:36 -05:00
David Wendt ef7c5d7eb9 Move XML properties to separate functions rather than closures 2020-01-05 00:17:57 -05:00
David Wendt 14dba0d100 Log errors encountered when removing the children of a node we plan to parse XML into.
Also, remove a handful of unnecessary `#[allow(unused_must_use)]` instances.
2020-01-05 00:04:45 -05:00
David Wendt 750e6e4370 Replace bare number constants for XML errors with symbolic `const` values 2020-01-04 23:56:10 -05:00
David Wendt fd541fabea Implement `status`.
I'm not entirely sure how to test this one - the list of errors that Flash kicks out for XML and the list of errors that `quick_xml` kicks out don't line up at all; so I just ensured that any error is a negative number (currently the one for OOM errors) and stuck whatever errors *did* match up together.

Consequently I don't know entirely *how* to write tests for this.
2020-01-04 19:00:49 -05:00
David Wendt f3226537bf Implement `idMap`.
`idMap` is a strange property; it's only populated with nodes which had a given `id` *at the time of parsing*, and said nodes continue to be referenced even if the node is removed from the document. I have yet to find a way by which nodes can be deleted from `idMap`.

It also takes expandos, so this has to be a new retained object on the XML document. I originally considered not creating *another* `Object` impl and populating a regular `ScriptObject` with nodes, but that meant we couldn't lazy-instantiate their AVM1 side counterparts. Boo. :/
2020-01-04 19:00:48 -05:00
David Wendt 823e8602ff Impl `XML.parseXML` 2020-01-04 19:00:46 -05:00
David Wendt d00ef01965 Add a convenience method: `XMLNode.into_string` 2020-01-04 19:00:46 -05:00
David Wendt 2c790f1d41 Filter non-AS2 compatible nodes from toString output, and add non-SWF tests for XML filtering. 2020-01-04 19:00:45 -05:00
David Wendt e2fa685d41 Fix tagname parsing.
There is a bug in `quick_xml` - or at least, I *think* it's a bug - where the `unescaped` method of `BytesStart` yields a bunch of attributes if you have slightly invalid crap in your tag like `xmlns:`. To work around it, I turned off unescaping; we're instead using `name` and ignoring unescaping. This will probably fail somewhere.
2020-01-04 19:00:44 -05:00
David Wendt e1034fce31 clippy compliance 2020-01-04 19:00:44 -05:00
David Wendt 7ac3204759 format prev commit 2020-01-04 19:00:43 -05:00
David Wendt 91155d6870 Text nodes have empty arrays for `childNodes` rather than being `undefined`. 2020-01-04 19:00:42 -05:00
David Wendt d28094a019 Implement `createElement` and `createTextNode`. 2020-01-04 19:00:42 -05:00
David Wendt c02da74afa Expose the `<?xml ?>` declaration to ActionScript.
I can't write proper tests for this because our underlying XML parsing technology doesn't let us do what AS2 XML does: just copy the first xml tag out of the document and into a string. No, seriously, anything at the start of the parsed XML that starts with `<?xml` and ends with `?>` gets copied into Flash's moral equivalent of `xml::Document` as a string. We parse the whole thing, which is wrong, so we'll need to additionally retain the original xmldecl string in order to pass the test I wrote for this.
2020-01-04 19:00:41 -05:00
David Wendt a7a349b02b Expose `docTypeDecl` to ActionScript.
This also involves storing the `DocType` node on the document object and retrieving it later.
2020-01-04 19:00:40 -05:00
David Wendt 6a472d32bb Filter incompatible nodes from the sibling and child lists. 2020-01-04 19:00:39 -05:00
David Wendt fd14d0c9df Doctype nodes should be represented as text nodes to ActionScript (if they somehow grab hold of them) 2020-01-04 19:00:38 -05:00
David Wendt aa749dc1b0 Store the XML document version, encoding, and standalone flags. 2020-01-04 19:00:38 -05:00
David Wendt a869107480 The `DocumentRoot` node type should have it's own node type ID, and AS2 XML should filter it out. This also filters out comment nodes as text, which isn't technically wrong but we should do better 2020-01-04 19:00:37 -05:00
David Wendt 673f85f067 XMLNode type 1 is an element, not a text node. 2020-01-04 19:00:36 -05:00
David Wendt c76e5ce447 appendChild also refuses to orphan nodes already part of another XML tree. 2020-01-04 19:00:35 -05:00
David Wendt 34cbe2e04b insertNode rejects child nodes that already have a parent 2020-01-04 19:00:34 -05:00
David Wendt 8c5dcfe662 Swap in newly constructed nodes *before* filling them with content.
Fixes a bug where new XML("<node />").childNode[0].parentNode did NOT refer to the overall document object, but to a phantom text node.

This is because the swap operation used to construct an XMLObject's node in-place was happening AFTER parsing, which means that referents already existed to the temporary XMLNode created by XMLObject::new. swap is not to be called after tree structure has been created; it does not update referents to the swapped nodes.

In the future I should examine the implications of explicitly reconstructing already existing nodes, e.g. through XML.apply(some_xml). Right now, the existing node will be swapped with a new one, and two nodes will exist pointing to the same script object, which is a huge problem with our overall design. We should, at the very least, disassociate swapped nodes from their script object, just in case they still have referents.

Ideally, we wouldn't have to swap nodes, but to avoid a swap, I'd have to instead have a second layer of indirection just to hold a rewritable pointer that every XMLObject points to. This isn't really worth it unless I HAVE to do it, so I'm not going to do it.
2020-01-04 19:00:32 -05:00
David Wendt 568d90f4dc Warn if XML.removeNode fails for whatever reason 2020-01-04 19:00:32 -05:00
David Wendt 19ca11b08c Impl `toString` 2020-01-04 19:00:31 -05:00
David Wendt 513460e4e0 Implement `insertBefore` 2020-01-04 19:00:31 -05:00
David Wendt b0dce445b0 Impl `removeNode` 2020-01-04 19:00:29 -05:00
David Wendt 00319f14a8 Implement `namespaceURI` 2020-01-04 19:00:29 -05:00
David Wendt abb2690367 When constructing new XML nodes or documents, always ensure that the new node we swap in is properly linked to the same script object so that we don't accidentally recreate them. 2020-01-04 19:00:28 -05:00
David Wendt 8939dae90c Implement `XMLNode.attributes` w/ read tests 2020-01-04 19:00:27 -05:00
David Wendt 6f48f3436f Expose `previousSibling` and `nextSibling` to ActionScript.
This commit also fixes a bug caused by excessive use of copypaste, which was detected by the included test.
2020-01-04 19:00:25 -05:00
David Wendt 223320c98c Expose `parentNode` to ActionScript 2020-01-04 19:00:24 -05:00
David Wendt 807725d7aa Expose `firstChild` and `lastChild` to ActionScript w/ tests 2020-01-04 19:00:24 -05:00
David Wendt 48d68bebc4 Implement `hasChildNodes()` and add test 2020-01-04 19:00:23 -05:00