Hi Greg, Could you please post the code from this email in the paste.apache.org - right now is unreadable in my Gmail account.
Thanks, Piotr On Sat, May 25, 2019, 4:51 AM Greg Dove <[email protected]> wrote: > OK, At the risk of making what follows even longer... a warning: *this is a > long read*. It might veer off topic in one or two places, but it is mostly > about why, and how Vector is implemented the way it is in the branch. > Basically I would like to merge this branch into develop as soon as > possible, i actually think it is ready as is, but I am keen to get other > input before I do. > Read it if you're interested. If you're not interested in reading it then > please try the branch on any 'real' projects that you have in play. Carlos > has tested against his, and there are no issues, but it would be good to > get wider input. > > now to the textual onslaught: > > > *Vector* > > One of the things I did before I worked on this Vector implementation was > to detach myself from ‘how I use Vector when I code’, to take a step back > and challenge myself to rethink how I thought about it in general. > > Vector is *special*. Vector is not *a class* in a typical sense. It is the > closest thing that as3 has to generics which, when used at a class level, I > like to think of as the ability to generate multiple class variations from > a single class definition (that is just the way I think of them). So, at > some level Vector could be considered as an infinite set of distinct > classes, based on an infinite set of possible specified element types > (whatever you see between the angle brackets in code). It is not actually > implemented natively in AVM this way iiuc, but that is the outward > appearance, and that is also the behaviour it has when using type checking > in as3. > > Aside from the runtime typesafe behaviour, Vector’s strong typing means > there is additional compile time support and, related, the possibility of > extra IDE support, both of which help the developer. > > Vector ‘types’ are also final ‘classes’ enforced by the compiler, so cannot > be extended. > > Additionally, on looking closer, there are some other quirky rules for > runtime typing behaviour. These are related to the implementation in AVM. > The 3 Vector types for Vector.<int>, Vector.<uint>, and Vector.<Number> are > individual base types, and then there is a 4th base type, Vector.<*> which > serves as the ‘base class’ of all other Vector ‘subclasses’. The 3 numeric > types are faster than Array, and I expect this was the reason for the > separation, because these are used in a lot of other flash apis, > particularly for swapping with byte level data and things like BitmapData > etc. The others are more simply for the strong typing aspects, because > (perhaps less so with Boolean and String at a guess) they are somewhat > slower than Array in AVM, because of the overhead of runtime typechecking > and coercions etc. So the main selling points for choosing a Vector in > flash were a) compile time and runtime type safety and b) faster > performance for the 3 numeric Vector types. > > One implication of these ‘rules’ means that to check if *something* is a > Vector of any type in swf, I need to do (mything is Vector.<int> || myThing > is Vector.<uint> || myThing is Vector.<Number> || myThing is Vector.<*>) or > use reflection (which is slower). > > The above implies that, for language conformance (considered as conformance > with as3 documentation/spec and the behaviour of the reference > implementation that we have for any ‘unknowns’) in an emulation, a regular > single as3 class implementation would not create a result that is > consistent with the spec in terms of its representation of typing, and its > behaviour when using type checking. > > I tried to take all of these things into consideration. > > > > *How is it implemented in the branch?* > > Vector is implemented using the lightweight ‘synthType’ approach I added > previously to support for int and uint types as ‘classes’. This provides a > light integration for ‘is’ and ‘as’ checks, but in javascript itself a > Vector instance is simply a tagged native javascript Array instance (i.e. > an Array with something that identifies it as being ‘not a regular Array’). > The Array methods are enhanced at the instance level to support the type > coercions that take place in an actionscript Vector. Using Array makes > sense because Vector instances are essentially typed Arrays. But it is not > possible to extend Array in javascript and have things work properly (it is > possible to use a different approach with es6 Proxy, but that is not > available in IE11). > > This implementation also means that a ‘Vector’ instance should have > functionality that works mostly as expected if it is passed directly to a 3 > rd party native javascript library that is expecting an Array instance. It > will not support errors when changing the length if the Vector instance is > ‘fixed’ length, for example but otherwise it should function much the same > as a regular Array in the 3rd party code. > > The ‘synthType’ approach can be used because Vector types are final, so it > does not need to conform to a regular Royale class definition that can be > extended and can be much ‘lighter’. As with int and uint ‘classes’, no > Vector constructor exists until the first one is requested. There is one > internal private class in Language that provides most of the functionality > for Vector, and element coercion functions are generated specifically for > each Vector ‘subtype’. Overall, it behaves more like a subclass ‘factory’ > with each individual type’s constructor being created on demand and cached > for future use. > > Reflection and serialization support have not been added yet, but I > certainly had these in mind also with this approach. I just wanted to reach > a sensible intermediate point for now, and then add those in later. > > In summary, the Vector implementation in the branch provides the following: > > -distinct types (conforming in terms of type checking) for each Vector > subtype > > -lightweight integration with Language ‘is’ and ‘as’ support > > -each Vector subtype has a unique constructor generated the first time it > is requested, the constructor does not exist prior to that. > > -expected to be compatible with 3rd party native javascript that expects a > regular javascript Array > > -serialization (amf) and reflection are not yet supported but were > considered, and that is planned as next steps. > > As at the time of writing, the current implementation is supported by 300 > Vector-specific assertions that run side-by-side between javascript and swf > in the manualtest UnitTests project. Apart from the differences created by > explicitly switching off some type safety checks with > @suppressvectorindexchecking, there is only one verifiable difference in > these tests between swf and javsacript. Probably there are things outside > the test coverage that might need addressing still, but I think it’s a > pretty good start. > > These tests should be easily ported to framework level unit tests > (RoyaleUnit) as the same approach has been used to add FlexUnit tests in > the past. Testing/Development is primarily in Chrome on windows, but the > same tests were subsequently verified on IE11, Edge, Opera and Firefox on > windows. > > *Implementation Info* > > *More quirks* > > A ‘fixed == true’ Vector cannot have its length changed. This means that > changes via the length setter and the mutation methods (push, pop, shift, > unshift etc) all throw errors if used when a Vector is ‘fixed == true’. > But… splice method also can change length. And in AVM this works even with > a fixed length Vector, which might possibly be a bug but is one that is > matched in the implementation to conform with flash. > > *Size impact.* > > Alex was concerned with size impact for HelloWorld because the beads were > using a Vector.<IBead> type in javascript in one of the application > framework base classes. But the requirement was for that to simply to be an > Array in javascript, the compiler was only achieving that by default > because there was no real Vector implementation. So I did a couple of > things here. Firstly I changed the application framework code to reflect > the different requirement for javascript. Secondly, I added some doc > comment directives to suppress exporting on public members. Then I added > this to the Language methods that are for compiler-generated Vector (and > int and uint) support so that they are eligible for dead code elimination > if not used. This effectively means that it is fully PAYG – it is only > there if you need it, but if you need it there is also no effort to add it > in as an optional dependency. If, because of this, there is a potential for > issues with modules or something I have not thought of, that will be > another thing to solve, but if so, I will find a way to address it. > > If the main concern with ‘size’ is data transfer, then looking at the > minified output size in HelloWorld is not really meaningful (or perhaps it > is better to say that it is only as meaningful as looking at the size of an > uncompressed swf compared to normal deployment of a compressed swf). In any > real deployment the javascript should be served as gzipped. So I compared > gzipped (‘normal’ compression) versions of HelloWorld.js between those with > the unused Language support methods (for int/uint and Vector) and their > dependencies vs. builds without. The support for all that functionality > comes in at under 3 Kb difference in the gzipped output. I personally don’t > think that would register as important in most cases. However, it is pretty > close to zero impact now if it is not used. In fact the HelloWorld > application is now about 55 bytes smaller than it was before, so I consider > it ‘carbon-netural’. And these are at the gzipped levels (it is also > slightly smaller when not gzipped, although it can sometimes be the case > that the larger of 2 files compresses better than a smaller one, depending > on the content). > > As a general comment about size… in my experience over the last 10 years or > so, mostly in relation to Flex apps, size was most often not among the > highest priority issues. Sure, start-up time often was. But that is not > size per se. Often ‘size’ issues were first and foremost ‘asset size’ > issues (embedded or separate). While I know overall that it remains > important, I personally think the growth in bandwidth and device memory in > general has outpaced the growth in the size of web apps even as the world > has turned to mobile. In other words, I think we probably passed a hurdle > point in the mobile side of things. Admittedly that is just ‘perception’ > and maybe there is data that shows I am quite wrong or your experience on > specific client projects could be quite different. The point of me > explaining that was, however, to illustrate why I think ‘size’ sits where I > think it does in general in terms of importance: I consider it to be behind > stability/reliability first which is followed by performance in performance > critical code. Overriding that general flow (which again, is just my > opinion), are whatever my client’s specific requirements are for any > particular project. In other words I am not sure how much of HelloWorld’s > size is going to be an important deciding factor for someone to choose to > use Royale. I think the ‘I got it to work!’ is the real kicker here. This > paragraph was not to cause any conflict, and I already addressed the ‘size’ > impact in the branch, so I’m not saying it wasn’t necessary to do that > (although I do suspect the same attention was not given to all other things > in the past that affected HelloWorld). It’s more to promote discussion and > thought in general. Trying to be all one aspect (small size) can compromise > other aspects (reliability or stability or compatibility, for example). And > trying to accommodate all aspects (reliability, small size, exceptional > performance) somehow very likely increases complexity because there is a > need to accommodate the explicit decisions for trade-offs between competing > aspects. It would be good to have a guide of priorities based on the needs > of the user base (while I might have a strong opinion about what I think is > important, I don’t assume that my views necessarily represent wider user > needs, because I have not done research to support that – and it’s not > really a twitter poll kind of thing!). Anyhow I got off track there a bit… > back to Vector… > > > > *Performance.* > > No-one should expect a non-native Vector implementation to perform faster > than native Array in javascript. Its main benefit is type safety, and that > is the reason it should be selected for use over Array. (In swf, native > numeric Vector types *are* selected for performance, but the other Vector > types are also at least slightly slower than Array, so selecting them is > based on the need for type safety) > > There are, however some ways to get 100% Array performance with this > implementation, and in a loop, for example it would be similar to avoiding > method calls (like push/pop) and only using index assignments that is > typical of performance optimization in swf. > > So these two methods provide almost Identical performance in js: > > > > > > > > > > > > > > > > > > > > > > > > > *private function testArrayInt2(iterations:uint):Number{ var start:Date > = new Date(); var inst:Array = new Array(iterations); for (var > i:uint=0;i<iterations; i++) { inst[i] = i; } return new > Date().valueOf() - start.valueOf(); } /** * * > @royalesuppressvectorindexcheck true */ private function > testVectorInt2(iterations:uint):Number{ var start:Date = new Date(); > var inst:Vector.<uint> = new Vector.<uint>(iterations); for > (var i:uint=0;i<iterations; i++) { inst[i] = i; } return > new Date().valueOf() - start.valueOf(); }* > > The doc comment on the 2nd method prevented the compiler from generating an > index check wrapper around the ‘i’ in inst[i] > > The above 2 methods take around 5-7 ms for 500,000 iterations on my machine > (chrome/windows). This is quite a bit faster than the same methods in the > swf (non-debug) build on my machine. The Vector constructor is also doing > extra work in this case by setting all the 500,000 slots to numeric 0. But > on modern browsers it is using a fast native Array.fill method to do that, > so it’s probably more noticeable on IE11 which uses a for loop to > pre-populate the contents with numeric 0 values. > > For reference, the generated code for the second method above, looks like > this: > > > > > > > > > > > > > > > > */** * * @royalesuppressvectorindexcheck true * @private * @param > {number} iterations * @return {number} */ > > flexUnitTests.language.LanguageTesterTestVectorPerf.prototype.flexUnitTests_language_LanguageTesterTestVectorPerf_testVectorInt2 > = function(iterations) { var /** @type {Date} */ start = new Date(); > var /** @type {Array.<number>} */ inst = new > (org.apache.royale.utils.Language.synthVector('uint'))(iterations); for > (var /** @type {number} */ i = 0; i < iterations; i++) { inst[i] = i; > } return new Date().valueOf() - start.valueOf(); };* > > The methods with type checking in them, like push, unshift etc will be > quite a lot slower though. This should not be a surprise. In swf, when you > look at something like Vector.<IBead> it can be up to 30% slower than Array > for methods like push, iirc at native level. In javascript it will be a lot > more. But in both cases it has type safety. And for small collection sizes > in non-performance sensitive code it is probably not going to make a > meaningul difference. > > Known limitations > > 1. myVectorInstance[‘constructor’] can be different between js and > swf > > 2. There is some reliance on not obscuring the type from the compiler > for things to work correctly. Example: > > var myObscuredType:* = new Vector.<String>(20,true) // creates a fixed > Vector of length 20 > > myObscuredType.length = 21; //should throw an error, but does not in > javascript. > > This will work as long as the compiler knows that the type with the length > setter is some type of Vector, otherwise not. > > > > *Performance tuning* > > *@royalesuppressvectorindexcheck* > > The above doc comment directive avoids checking for out-of-valid-range > index values on assignments. This is extremely desirable inside loops which > are usually constrained to the valid range in any case. There is a top > level compiler configuration setting for this, but local settings win > (turning off or on generally with true/false, or suppressing specifically > for individual local variable names) > > > > Other options. > > The above one was obvious to me as an important tuning option. I started > with adding another but pulled it out in favor of adding them based on > actual need. > > There are many options: > > Instance based: reducing type checking with a compiler-only generated > additional constructor parameter, triggered by some doc comment directive. > This could be in the form of adding in compiler generated alternatve calls > to things like ‘unsafePush’ and ‘unsafePop’ on instances, or perhaps > literal calls to Array.prototype.push.call(inst, pushItem), triggered by > some doc comment directive > > Global changes:Adding some compiler define value that (along with: > ||goog.DEBUG) suppresses many runtime checks in the release Vector > implementation. This would allow a blanket approach to dialing runtime > safety down (or keeping them) in the release build. It would apply across > all libraries and local project code. > > Some combinations of the above that allow sweeping optimizations with local > exceptions. > > Basically, this branch currently represents what I have reason to believe > is a high conformance Vector implementation which should be the default as > it is an as3 core type. I think there are many options to scale things > back, but rather than assume what they should be, I’d prefer to hear from > users and address *real* needs, so that we only end up with configuration > options that matter. > > > > *Advantages of a single Vector implementation – the case for avoiding a > ‘vector emulation class’* > > ‘Language emulation’ is a foundational layer that is not in the same > category as ‘application framework’ where we can define things how we want. > Because the royale sdk includes both aspects inside ‘framework’ (and that > was obviously not the case for flex sdk in the past) it may be easy to > overlook that difference. > > Vector typing is a core part of AS3 language. Therefore it should conform > and be reliable. Having multiple implementations for a core language > feature seems wrong and could easily lead to libraries of code that are > incompatible. Additionally, as pointed out earlier, Vector is more like a > subclass factory (‘runtime’ generics) than a single class, so won’t be well > represented by a regular class implementation. > > Alex, I know you added support for a Vector emulation class approach to > meet the needs of someone asking for improved Vector support, in part > because we did not have someone who had volunteered to write our own. I did > that last part now. I am also suggesting that the emulation class approach > is not a good long term solution because of the above reasons. And the full > set of functionality is less than 3Kb in the gzipped output, so I’d suggest > that as long as I can add needs-based performance tuning options for those > who want them, the benefits of having a single conforming implementation > which is performance scalable are better than the risks associated with > adding partially non-conforming ones. Therefore I’d like to ask if we can > remove that functionality now that we have our own 'Vector' (I can do the > work if you prefer as I know your focus is understandably on other things). > > *Future:* > > It will be easily possibly to alter the current implementation to use es6 > proxy which would likely provide the most reliable way to get full Vector > conformance indistinguishable from flash. Es6 proxy is transparent for > Array: > > var p = new Proxy(new Array(), {}); > > Array.isArray(p) // true > > This should allow trapping things like the length setter before it gets to > the underlying Array target, and doing checking for fixed == true etc. The > same is true for numeric index-based assignment of values etc. > > es6 Proxy is kinda cool. At the moment IE11 is the only meaningful target > that does not support this. > > I am only mentioning this here because I did think about this, and I > believe that the current implementation could be upgraded quite easily to > use this approach if it makes sense (when IE11 is a distant memory – > perhaps sometime next year!). > > > > Phew, you made it! Well done. > > Feel free to share your thoughts or ask any questions you might have. If > you have neither of those at this time, please still try to find time to > test any large projects you have in the branch, and provide feedback or > share any concerns you might have after doing that. > thanks, > Greg > > > On Thu, May 23, 2019 at 7:55 PM Greg Dove <[email protected]> wrote: > > > Re XMLTest manualtest... > > > > Yep those were the ones I ported, Harbs. I think I got them all but may > > have missed some. I added a bunch more as well. Hopefully these can be > > easily migrated to what Josh has been working on. > > > > > > On Thu, 23 May 2019, 19:43 Harbs, <[email protected]> wrote: > > > >> As far as XML unit tests go, the starting point should be XMLTest in > >> manual tests. (Almost) every time I ran into an issue, I added it to > that > >> project. > >> > >> I think I might have been lax on the last few issues I fixed, so we > >> should probably go through the later XML commits and make sure we have > >> tests for that. > >> > >> As far as Node goes, I think we probably need conditional Node > >> compilation to handle Node-specific (and browser specific) code in a > PAYG > >> way. > >> > >> To technically handle the parsing, something like > >> https://github.com/isaacs/sax-js <https://github.com/isaacs/sax-js> is > a > >> good starting point and something like this > >> https://github.com/nfarina/xmldoc <https://github.com/nfarina/xmldoc> > >> might be useful to either use or modify. > >> > >> Harbs > >> > >> > On May 23, 2019, at 10:18 AM, Greg Dove <[email protected]> wrote: > >> > > >> > All, I started porting some adhoc XML tests to UnitTests and > eventually > >> > ended up spending quite a bit of time on addressing issues that arose > >> for > >> > XML before getting back to Vector stuff. > >> > I think XML probably needs many more unit tests before we get to 1.0 > >> > because it has an extensive api. I have not used royale with Node yet, > >> but > >> > XML also needs some thought about how to get it working on Node, I > >> assume. > >> > Because XML uses the browser's parser and Node does not have one by > >> > default, then using the same code will need something to take the > place > >> of > >> > the browser's native parser for Node. There is a lib in npm that might > >> be > >> > useful for that, but I don't know how that might work with licence > etc. > >> > Anyhow, that is just an observation, I will focus on Vector in this > >> > thread... I will post here late tomorrow local time with more info, > and > >> > discussion points. I am keen to see this merged in, but also keen to > get > >> > buy-in first. > >> > > >> > > >> > On Fri, May 10, 2019 at 11:15 PM Carlos Rovira < > [email protected] > >> > > >> > wrote: > >> > > >> >> Hi Greg, > >> >> > >> >> thanks for reporting. I can share here that I was able to test your > >> branch > >> >> with our real project and seems all goes well. > >> >> Could make a intense test, but almost app is working and we found > just > >> a > >> >> few type error coercions that your code was able to catch (so great! > >> :)) > >> >> and must be solved as you merge the branch in. > >> >> > >> >> I think that if Vector is something new and others don't have > >> problems, the > >> >> branch can be merged and Vector discussions can be done after that, > >> since > >> >> it will not break anything since there's no uses of that code since > is > >> new, > >> >> but the other changes can be very beneficial > >> >> > >> >> thanks in advance for your progress in all this stuff :) > >> >> > >> >> Carlos > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> El vie., 10 may. 2019 a las 8:44, Greg Dove (<[email protected]>) > >> >> escribió: > >> >> > >> >>> All, I am really sorry, I keep thinking I will be able to get back > to > >> >> this, > >> >>> but I have some other personal things taking my spare time at the > >> moment. > >> >>> These will be done in 2 days, and I then will update the branch with > >> some > >> >>> extra stuff, and continue this discussion with a focus on Vector > >> >> (bringing > >> >>> some other relevant discussion on the same topic from Alex as well) > at > >> >> that > >> >>> time. Sorry to set the wrong expectations earlier. > >> >>> > >> >>> > >> >>> On Tue, May 7, 2019 at 9:01 AM Greg Dove <[email protected]> > wrote: > >> >>> > >> >>>> Thanks for the feedback, Josh, Carlos, Alex. > >> >>>> > >> >>>> js-complex-implicit-coercions > >> >>>> js-resolve-uncertain > >> >>>> js-vector-index-checks > >> >>>> > >> >>>> I will make those changes for compiler settings at some point in > the > >> >>>> branch later today, invert the config default values to match, and > >> swap > >> >>> all > >> >>>> 'off' settings in the framework builds (ant and maven) from true to > >> >>> false. > >> >>>> I will also add compiler tests for these settings (either today or > >> >>>> tomorrow). At the moment I only tested the new settings in the code > >> >>> result > >> >>>> tests in javascript. > >> >>>> > >> >>>> In another day or two I will post a call to discuss the Vector > >> >>>> implementation in more detail. For Vectors, the > >> js-vector-index-checks > >> >>> was > >> >>>> the obvious first candidate for dialing back on the impact of > runtime > >> >>>> type-checking, but there are a number of options for 'dialing' > other > >> >>>> aspects back (or even forward) and choosing the scope of their > effect > >> >>>> (local code, local project, or entire codebase code including > >> external > >> >>>> swcs). I already had stub code for the start of something else to > >> >> remove > >> >>>> typechecking in mutation methods ('push', 'shift', 'pop' etc) but > >> >> removed > >> >>>> it in favour of discussing and reviewing it first. Coming up with > a > >> >>>> 'usable' set of options will really benefit from your collective > >> input, > >> >>> so > >> >>>> I hope you can participate. > >> >>>> > >> >>>> > >> >>>> > >> >>>> > >> >>>> > >> >>>> On Tue, May 7, 2019 at 4:19 AM Alex Harui <[email protected] > > > >> >>>> wrote: > >> >>>> > >> >>>>> +1 to renaming the options to the positive. > >> >>>>> > >> >>>>> On 5/6/19, 8:12 AM, "Josh Tynjala" <[email protected]> > wrote: > >> >>>>> > >> >>>>> Hey Greg, > >> >>>>> > >> >>>>> I haven't had a chance to look through all of the changes, but > >> one > >> >>>>> thing caught my eye. I find it confusing when a boolean value is > >> named > >> >>> with > >> >>>>> a "negative" phrase. For instance, your new compiler options have > >> "no" > >> >>> in > >> >>>>> the name: > >> >>>>> > >> >>>>> js-no-complex-implicit-coercions > >> >>>>> js-no-resolve-uncertain > >> >>>>> js-no-vector-index-checks > >> >>>>> > >> >>>>> As they are named, true means no, and so false means yes. With > >> >> this > >> >>>>> kind of naming, I find that I always need to take a moment to > >> remember > >> >>>>> which means which. I think it would be better if true means yes > and > >> >>> false > >> >>>>> means no. > >> >>>>> > >> >>>>> - Josh > >> >>>>> > >> >>>>> On 2019/05/05 08:00:20, Greg Dove <[email protected]> wrote: > >> >>>>>> So... just an overview of recent work I have been doing. > >> >> Summery > >> >>>>> up front, > >> >>>>>> some extra detail further down... please try things with the > >> >>> branch > >> >>>>> if you > >> >>>>>> have time. > >> >>>>>> > >> >>>>>> In the *improvements/Language* branch there are many updates > >> >>> inside > >> >>>>>> Language and related updates inside the compiler to address > >> >> these > >> >>>>> main > >> >>>>>> areas: > >> >>>>>> -Fixes/better support for int and uint types at runtime > >> >>>>>> -Fixes for strict equality comparisons when instantiated types > >> >> are > >> >>>>>> uncertain, or known to be problematic in these cases for > >> >> specific > >> >>>>> types > >> >>>>>> that are known. > >> >>>>>> -Complex implicit coercions (throws errors if assigned type is > >> >>>>> incorrect) > >> >>>>>> -Vectors - test-driven development of a conforming > >> >> implementation. > >> >>>>>> > >> >>>>>> The new features are supported by almost 350 new assertion tests > >> >>>>> (in the > >> >>>>>> UnitTests manualtests project). This was not a trivial amount of > >> >>>>> work :) > >> >>>>>> > >> >>>>>> I still have a few things to work on in the branch, including > >> >> some > >> >>>>> tuning > >> >>>>>> for the new configuration settings and adding tests to the > >> >>> compiler > >> >>>>> for > >> >>>>>> those, but I would be keen for others to test the branch and try > >> >>> it > >> >>>>> with > >> >>>>>> real projects, and provide feedback. So this is > >> >>>>> 'improvements/Language' for > >> >>>>>> both royale-asjs and royale-compiler. > >> >>>>>> In particular, please take Vector for a spin and see if you can > >> >>>>> break > >> >>>>>> anything and let me know! > >> >>>>>> Note the new configuration settings a bit further down (and see > >> >>>>> examples > >> >>>>>> here for how to switch them off globally: > >> >>>>>> mvn: > >> >>>>>> > >> >>>>> > >> >>> > >> >> > >> > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-asjs%2Fblob%2Fimprovements%2FLanguage%2Fframeworks%2Fprojects%2Fpom.xml%23L88&data=02%7C01%7Caharui%40adobe.com%7Ce44a5f9a81b141a8414908d6d2352ee6%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636927523209585267&sdata=ZDbgmmsdx4m6D9Bnel839Lxi4sVh8kwNLKK4HS%2F%2ByW8%3D&reserved=0 > >> >>>>>> ant: > >> >>>>>> > >> >>>>> > >> >>> > >> >> > >> > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-asjs%2Fblob%2Fimprovements%2FLanguage%2Fframeworks%2Fjs%2Fprojects%2FBasicJS%2Fsrc%2Fmain%2Fconfig%2Fcompile-js-config.xml%23L106&data=02%7C01%7Caharui%40adobe.com%7Ce44a5f9a81b141a8414908d6d2352ee6%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636927523209585267&sdata=kvr13pxvGktxjV7QLu0mWdKJZfpr3zk6AHCj%2FM74Ym4%3D&reserved=0 > >> >>>>>> ) > >> >>>>>> > >> >>>>>> > >> >>>>>> A couple of examples: > >> >>>>>> I tried compiling Tour de Jewel with the new features switched > >> >> on, > >> >>>>> it it > >> >>>>>> immediately highlighted a runtime error where a 'bead' was being > >> >>>>> added > >> >>>>>> which was not actually an IBead. This was detected in a Vector > >> >>> push > >> >>>>>> operation. Although it was not causing problems, it is a good > >> >>>>> example of > >> >>>>>> something that would have failed at runtime in the flash player, > >> >>>>> making it > >> >>>>>> much easier to identify and fix. > >> >>>>>> > >> >>>>>> I have switched the extra outputs off for all the framework code > >> >>> in > >> >>>>> the > >> >>>>>> branch. But I did try a couple of projects with them on. As an > >> >>>>> example, > >> >>>>>> after building XML with them on it throws a runtime error when > >> >>>>> calling one > >> >>>>>> of the methods in XML. > >> >>>>>> The method has the wrong argument type (Element type when it > >> >>> should > >> >>>>> -iirc- > >> >>>>>> be Node). So these can catch errors in your code that are silent > >> >>>>> because > >> >>>>>> there is no strong typechecking at runtime. > >> >>>>>> The above is the implicit complex coercion in action. it is like > >> >>> if > >> >>>>> you did > >> >>>>>> in flash player : > >> >>>>>> var myArray:Array = [new ByteArray()]; > >> >>>>>> var sprite:Sprite = myArray[0]; //runtime error here > >> >>>>>> This does not happen currently in Royale javascript, but is now > >> >>>>> supported > >> >>>>>> in the branch (and you can switch it off). This is an expansion > >> >> of > >> >>>>> some of > >> >>>>>> Josh's great work in the past with implicit primitive coercions > >> >>>>> (which > >> >>>>>> don't throw errors but coerce to the correct type). > >> >>>>>> > >> >>>>>> *New configuration settings* > >> >>>>>> js-no-complex-implicit-coercions > >> >>>>>> default: false (i.e. ensures runtime safety when assigning an > >> >>>>> unknown type > >> >>>>>> to a known type ) > >> >>>>>> local doc comment directive > >> >>>>>> switching: @royalesuppresscompleximplicitcoercion > >> >>>>>> > >> >>>>>> js-no-resolve-uncertain > >> >>>>>> default: false (i.e. ensures instances that are safe in certain > >> >>>>>> comparisons ) > >> >>>>>> local doc comment directive switching: > >> >>>>> @royalesuppressresolveuncertain > >> >>>>>> > >> >>>>>> js-no-vector-index-checks > >> >>>>>> default: false (i.e. vector index checking is on) > >> >>>>>> local doc comment directive switching: > >> >>>>> @royalesuppressvectorindexcheck > >> >>>>>> > >> >>>>>> *-Fixes problems/provides more general support for int and uint > >> >>>>> types at > >> >>>>>> runtime* > >> >>>>>> Josh's recent assignment implicit coercions made a big > >> >> difference > >> >>>>> for these > >> >>>>>> (and other primitive types), but runtime support either caused > >> >>>>> errors or > >> >>>>>> bad results. > >> >>>>>> Things like > >> >>>>>> var myClass = int; > >> >>>>>> > >> >>>>>> var x:* = new myClass(22.5); > >> >>>>>> trace( x === 22 ) //true > >> >>>>>> > >> >>>>>> The above works now in the branch. iirc I think there is more > >> >> than > >> >>>>> one > >> >>>>>> issue with that in develop. > >> >>>>>> I started with this based on issue #273 which also now is fixed > >> >> in > >> >>>>> the > >> >>>>>> branch. > >> >>>>>> > >> >>>>>> int and uint are implemented are not needed like this in most > >> >>>>> cases, so the > >> >>>>>> are not real 'classes' but very simple instances of 'synthetic > >> >>>>> Types' that > >> >>>>>> are only 'created' if/when they are requested for the first > >> >> time. > >> >>>>> Vectors > >> >>>>>> (because they are kind of like factory-generated classes) use > >> >> the > >> >>>>> same > >> >>>>>> underlying mechanism, but are more complicated than int and uint > >> >>> in > >> >>>>> terms > >> >>>>>> of their supporting implementation. uint and int are almost > >> >>> defined > >> >>>>> in a > >> >>>>>> single line of code, not so for Vectors. Another candidate for a > >> >>>>> synthetic > >> >>>>>> type might be 'Class', but I will see about that. > >> >>>>>> > >> >>>>>> *-Fixes for strict equality comparisons in when instantiated > >> >> types > >> >>>>> are > >> >>>>>> uncertain, or known to be problematic for types that are known.* > >> >>>>>> Certain explicit instantiations of primitive types are swapped > >> >> to > >> >>>>> coercions. > >> >>>>>> Things like 'new String('test')' are now output simply as > >> >>>>> String('test'). > >> >>>>>> Resolution of uncertain instantiations > >> >>>>>> Where a class is not known, the instantiation of that class is > >> >>>>> wrapped in a > >> >>>>>> 'resolveUncertain' method call. This calls the low level native > >> >>>>> 'valueOf()' > >> >>>>>> method on the instance, which resolves it to primitive types if > >> >>>>> possible. > >> >>>>>> > >> >>>>>> The above changes provide consistency with AVM when values , > >> >> even > >> >>>>> those > >> >>>>>> with typing obscured, are used in strict equality comparisons. > >> >>>>> These cases > >> >>>>>> may not bet mainstream, but that is exactly the type of thing > >> >> the > >> >>>>> causes a > >> >>>>>> lot of headscratching when things don't work. Note that > >> >>>>> Array.indexOf also > >> >>>>>> uses strict equality comparisons, so this is not just fixing > >> >>>>> results of === > >> >>>>>> or !== across these edge cases. > >> >>>>>> > >> >>>>>> *-Complex implicit coercions* > >> >>>>>> I expanded on Josh's implicit primitive type coercions to > >> >> support > >> >>>>> more > >> >>>>>> complex coercions > >> >>>>>> (this is on by default, but explicitly off in the framework) > >> >>>>>> So this works now like flash player: > >> >>>>>> var myClass:MyClass = someArray[i]; //if the assigned value from > >> >>>>>> someArray[i] is not a MyClass type, error is thrown > >> >>>>>> This can be switched off at compiler level, or tuned within > >> >>> methods > >> >>>>> (on or > >> >>>>>> off in contrast to compiler level setting) with a specific doc > >> >>>>> comment > >> >>>>>> directive. (i.e. like royaleignorecoercion) > >> >>>>>> Output in debug mode shows these implicit coercions prefixed > >> >> with > >> >>>>> /* > >> >>>>>> implicit cast */ so you can easily review the number of > >> >> locations > >> >>>>> this is > >> >>>>>> affecting by doing 'find in files' and looking at the locations > >> >>> and > >> >>>>> count. > >> >>>>>> While it will probably be a good thing to switch off in a final > >> >>>>> release > >> >>>>>> build, it can help find problems during development, > >> >> particularly > >> >>>>> as more > >> >>>>>> and more code is not being parallel tested in the flash player > >> >>>>> where error > >> >>>>>> trapping like this is automatic. > >> >>>>>> I switched this off in framework, but it could help find code > >> >>>>> errors in the > >> >>>>>> framework when it is switched on > >> >>>>>> > >> >>>>>> > >> >>>>>> *-Vectors* > >> >>>>>> Vectors are 'smoke and mirrors' currently in develop - it is > >> >>>>> basically the > >> >>>>>> compiler pretending that they are Vectors (they are Arrays). > >> >> This > >> >>>>> gives a > >> >>>>>> small amount of compile time safety, but still leaves large gaps > >> >>>>> when > >> >>>>>> compared with the real thing and many things that you could > >> >> assume > >> >>>>> would be > >> >>>>>> safe will not be. Assuming it worked properly could be even > >> >>>>> considered a > >> >>>>>> little 'dangerous'. > >> >>>>>> > >> >>>>>> There are 260 new assertion tests for Vectors, including some > >> >> that > >> >>>>> relate > >> >>>>>> to a new doc comment directive @suppressvectorindexchecking > >> >> which > >> >>>>> avoids > >> >>>>>> (intensive) checking for range errrors (and will be desirable to > >> >>>>> switch off > >> >>>>>> in a lot of cases, such as in length constrained loops etc). > >> >>>>>> You can see the Vector tests here: > >> >>>>>> > >> >>>>> > >> >>> > >> >> > >> > https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fapache%2Froyale-asjs%2Fblob%2Fimprovements%2FLanguage%2Fmanualtests%2FUnitTests%2Fsrc%2Fmain%2Froyale%2FflexUnitTests%2Flanguage%2FLanguageTesterTestVector.as%23L65&data=02%7C01%7Caharui%40adobe.com%7Ce44a5f9a81b141a8414908d6d2352ee6%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636927523209585267&sdata=NNJ6cfAOqGHPya5oyADDhwBwkWpNkng%2Fk0%2BvrzZm7aM%3D&reserved=0 > >> >>>>>> > >> >>>>>> > >> >>>>>> > >> >>>>>> *Miscellaneous* > >> >>>>>> -When addressing some sourcemap related stuff for Vectors, I > >> >> fixed > >> >>>>> an > >> >>>>>> unrelated sourcemap issue that was caused by methods which had > >> >>>>> metadata > >> >>>>>> attached. The mapping now correctly aligns with the original > >> >>>>> function > >> >>>>>> keyword in these cases. > >> >>>>>> > >> >>>>> > >> >>>>> > >> >>>>> > >> >>> > >> >> > >> >> > >> >> -- > >> >> Carlos Rovira > >> >> http://about.me/carlosrovira > >> >> > >> > >> >
