亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? stack_inversion.txt

?? javascript擴展庫
?? TXT
字號:
7/24/06This document describes some specifics of the Alpha2 release of Narrative JavaScript, and fleshes out some thoughts about a different implementation strategy.----------------------------------------I've been contemplating how yield and resume are implemented in Narrative JavaScript, and I'm starting to think that there's an alternative strategy that will prove more elegant and natural at the expense of slightly more implementation complexity.In order to discuss how narrativejs may reimplement its yield/resume algorithms, let's first discuss the problem space and review how the current code generation process works.The narrativejs compiler works as follows: it finds function declarations that use the -> operator (i.e. contain yielding method calls) within the body, and then it rewrites these functions by doing the following:- reorganize the function body to act like a state machine- bundle all local context data into a referenceable object- modify all local data references to operate on the context object- modify yielding method calls so that the context is appended to the callee's parameter listAt runtime, the contexts that are passed into successive yielding method calls are linked together, thus forming a runtime representation of the current stack.  It's this context data that's used to resume execution (at the point just after execution yielded) upon asynchronous callback.A thread is resumed by setting a return value at the top of the context chain and calling the method corresponding to the top context object.  (Remember, the methods have been rewritten to be state machines.  This means that we can jump into the middle of a method simply by supplying the correct context data as an argument.)  When that method "returns", it repeats the steps just described: grab the next lower frame context, set a return value, and call the corresponding method.For example, if we have functions A, B, and C, where A calls B->() and B calls C->(), here's a moment by moment view of the stack prior to yield:  1. A  2. A B      // A calls B->()  3. A B C    // B calls C->()  4. [yield]Then, when we resume, the stack begins at the "top" and goes to the "bottom":  1. [resume]  2. C  3. C B    // C resumed B  4. C B A  // B resumed AThis process of chaining context jump-points together is very similar to continuation-passing-style coding (although as Chris Double has pointed out it's not quite the same because these aren't true continuations).  Take note that when we resume, the stack is reversed from it's original direction.  I call this "stack inversion," and its existence lies at the center of this discussion.  Also note that the diagrams above aren't quite technically correct, but we'll get back to that later.This CPS-like process is a fine implementation, and it works reasonably well enough.  However, there are 3 potentially troubling problems:* Problem 1: It is easy to run out of stack space using narrativejs.This can happen if you resume without yielding -- the stack just continues forever upward.  For example, assume method C above didn't yield to the runtime, and A had been coded such that it called back into B multiple times.  The stack would just keep growing:  1. A  2. A B            // A called B->()  3. A B C          // B called C->()  4. A B C B        // C resumed B  5. A B C B A      // B resumed A  6. A B C B A B    // A looped, called B->() again  7. A B C B A B C  // B called C->()  etc.* Problem 2: Native stack traces don't include the correct caller.Since the stack is inverted when we resume, a native stack trace (such as you might see in a debugger) won't show the caller method that was present prior to yield.  Instead, you see callee methods that are now complete.  The correct caller data is present in the runtime via the context object chain, but that's not helpful for debugging.  So while narrativejs improves code clarity, it unfortunately does not help (and even hinders) code debuggability.* Problem 3: Methods that don't yield behave differently than methods that do.As pointed out by Joe and Kris on the narrativejs mailing list, a method called via -> that does not in fact yield will result in premature thread termination.  This is because of how the CPS-like transform works: yielding methods "return" by calling their caller, whereas regular methods simply return as normal.  The compiler doesn't check for the situation where a non-yielding method is called with ->, therefore its return is treated as a yield, and the thread is never resumed.Solution?---------At the heart of all three of the problems above is the fact that the narrativejs implementation results in stack inversion as described earlier.  If yielding resumed with the stack in its upright position, I think it would be possible to generate the code such that none of these problems would exist.How would this be possible?  Well, my first thought is to resume execution by crawling to the head of the context chain, call its corresponding method, and rely on the state-machine qualities of each method to result in no-op re-calling of each method in the chain, thus re-establishing the stack that existed prior to yield.  For example:  1.  A  2.  A B  3.  A B C  4.  [yield]  5.  [resume]  6.  A        // no-op -- state machine jumps directly to B->()  7.  A B      // no-op -- state machine jumps directly to C->()  8.  A B C    // resumes C after the yield point  9.  A B      // C returns, resuming B  10. A        // B returns, resuming ASo in other words, the stack would be re-established by calling methods in order of the context chain, but the actual resume of each frame would happen on the way back down, on *return*.  (As opposed to typical CPS and the current implementation, which resumes on *call*.)Since resume would now happen on return, calling up into a non-yielding method can be made safe: prior to a -> method call, the context is configured to resume as normal when the callee returns. On the other hand, yielding now becomes an explicit action that modifies the context so that it doesn't resume until later.  (I find this mind-bending.  I had to chew on it for a while to get it.)My first knee-jerk reaction to this idea is, "yuck, now we're performing way more stack operations that we were before. I'm not sure about the performance overhead of this algorithm."  It seems like a reasonable argument at first glance -- not only do you call A, B, and C to get to the yield point, but you have to do the exact same thing to resume after the yield point.But my knee-jerk reaction is unwarranted.  Upon further examination it's easy to see that there's no extra overhead involved in resuming the stack from the bottom going up.At this point we need to digress into a brief discussion of tail recursion.  Continuation passing style was originally conceived and implemented in languages that support proper tail recursion.  For those who don't remember this concept from their way-back college days: tail recursive languages remove portions of the stack that are determined to be complete.  In other words, if when leaving a frame the runtime is able to determine that no operations will be executed once the frame is returned to, the runtime can (and will) safely remove that frame from the stack.  In this way a language implementation can optimize for stack space.  For example, in a tail recursive language our stack progression would look like this:  1. A  2. B   // A is discarded  3. C   // B is discarded  4. [yield]  5. [resume]  6. C  7. B   // C is discarded  8. A   // B is discardedIn addition to less stack space, this also helps efficiency in that you have fewer return operations, which means you have fewer overall stack manipulations.JavaScript 1 does not support proper tail recursion.  This means that any method call *always* results in 2 stack manipulations: when calling, add the method to the stack, and then the frame is removed on return.  This makes a big difference in how we must think about the yield and resume process.Let's return to our original diagrams, the ones I said weren't quite technically correct.  The reason they weren't correct is because they don't show the return operations corresponding with each method call.  So let's revisit the stack progression in narrativejs as it exists now, with stack inversion.  This time, we'll include the return operations (each stack change that doesn't really cause any meaningful code to be executed is marked as "no-op"):  1.  A  2.  A B        // A calls B->()  3.  A B C      // B calls C->(), C yields  4.  A B        // C returned (no-op)  5.  A          // B returned (no-op)  6.  [yield]    // A returned (no-op)  7.  [resume]    8.  C          // resume C  9.  C B        // resume B  10. C B A      // resume A  11. C B        // A returned (no-op)  12. C          // B returned (no-op)  13.            // C returned (no-op)Now, let's compare with an algorithm that doesn't invert the stack:  1.  A  2.  A B        // A calls B->()  3.  A B C      // B calls C->(), C yields  4.  A B        // C returned (no-op)  5.  A          // B returned (no-op)  6.  [yield]    // A returned (no-op)  7.  [resume]  8.  A          // re-establish A on the stack (no-op)  9.  A B        // re-establish B on the stack (no-op)  10. A B C      // re-establish C on the stack (C resumes)  11. A B        // C returned (B resumes)  12. A          // B returned (A resumes)  13.            // A returned (no-op)There's no difference in the number of operations!  Unless I'm missing something, It's unintuitive but true: CPS transform provides no benefits and a few drawbacks when used in a language missing tail-recursive.This right-side-up algorithm is different enough from CPS that I wouldn't say it's correct to call it CPS anymore.  Instead I'm thinking of it as "co-routine emulation".The only potential drawbacks to co-routine emulation that I'm seeing right now are a) increased implementation complexity, and b) bloated size of rewritten code.  I'm not too worried about (a), but (b) I'm pretty sensitive to.  I'm currently thinking through implementation ideas that minimize the impact of (b).  In the meantime, thoughts and comments are appreciated.  -Neil

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美精品一区二区三区四区 | 日本在线不卡视频一二三区| 99国内精品久久| 中文字幕五月欧美| 一本大道久久a久久精品综合| 亚洲丝袜制服诱惑| 欧美日韩五月天| 蜜臀va亚洲va欧美va天堂| 精品美女在线观看| 国产精品夜夜嗨| 亚洲三级电影网站| 欧美日韩不卡一区二区| 国内精品视频一区二区三区八戒| 久久九九影视网| 91蝌蚪porny成人天涯| 亚洲亚洲人成综合网络| 精品日韩在线观看| 99久久久免费精品国产一区二区| 一区二区日韩电影| 精品美女一区二区三区| 99久久精品久久久久久清纯| 亚洲成人免费在线| 久久婷婷国产综合国色天香| 91在线视频免费91| 麻豆精品精品国产自在97香蕉| 国产日韩精品一区二区浪潮av| 在线精品国精品国产尤物884a| 日本不卡的三区四区五区| 国产精品污污网站在线观看| 欧美优质美女网站| 国产美女久久久久| 亚洲一区二区三区小说| 久久久久国色av免费看影院| 色欧美日韩亚洲| 国产一区999| 香蕉影视欧美成人| 最新日韩av在线| 日韩精品一区在线观看| 91福利视频久久久久| 激情六月婷婷久久| 亚洲第一会所有码转帖| 国产精品久线在线观看| 日韩欧美一级二级| 日本韩国精品在线| 国产精品白丝jk黑袜喷水| 丝袜脚交一区二区| 中文字幕一区二区三中文字幕| 777奇米成人网| 99re成人在线| 国产精品18久久久久久久久| 五月婷婷色综合| 一区二区三区在线观看网站| 国产婷婷一区二区| 欧美大白屁股肥臀xxxxxx| 91成人免费在线| 91精品国产福利在线观看| 成人小视频免费在线观看| 日本伊人色综合网| 亚洲一区电影777| 亚洲美女精品一区| 亚洲色图一区二区| 国产精品毛片高清在线完整版| 日韩视频中午一区| 91精品国产综合久久久久久久| 在线中文字幕一区二区| 96av麻豆蜜桃一区二区| 成人av片在线观看| 成人午夜激情在线| 成人高清视频免费观看| 懂色中文一区二区在线播放| 激情小说亚洲一区| 久久国产免费看| 国内外成人在线| 极品少妇一区二区| 国产一区视频导航| 国产一区二区三区av电影| 国产资源在线一区| 国内精品伊人久久久久av影院| 精品亚洲欧美一区| 国产一区二区久久| 国产suv精品一区二区三区| 国产成人av网站| 成人涩涩免费视频| 91免费国产视频网站| 91麻豆免费看片| 91搞黄在线观看| 337p亚洲精品色噜噜狠狠| 日韩欧美一二三四区| 久久久久久久综合日本| 国产精品久久久久久久久免费相片 | 日韩欧美一区二区三区在线| 日韩亚洲欧美在线观看| 精品国产精品一区二区夜夜嗨| 精品毛片乱码1区2区3区 | 制服.丝袜.亚洲.另类.中文| 91精品国产综合久久精品app| 欧美一区二区视频在线观看2022| 精品美女在线播放| 国产精品不卡一区| 亚洲成在人线免费| 国产一级精品在线| 99视频在线观看一区三区| 色老汉一区二区三区| 7777精品伊人久久久大香线蕉最新版| 欧美一区二区不卡视频| 国产性做久久久久久| 玉米视频成人免费看| 老司机精品视频在线| 成人h动漫精品一区二| 欧美视频一区在线| 久久综合成人精品亚洲另类欧美| 中文字幕日本不卡| 青青草国产精品亚洲专区无| 国产成人免费9x9x人网站视频| 一道本成人在线| 精品国产一区二区三区久久久蜜月 | 3751色影院一区二区三区| 日本一区二区三区国色天香| 亚洲一区二区三区三| 国产精品中文字幕一区二区三区| 色婷婷综合久久久久中文| 日韩一区二区影院| 亚洲人成亚洲人成在线观看图片| 日韩av一级片| 99re免费视频精品全部| 欧美成人综合网站| 亚洲图片一区二区| 国产精品一区二区无线| 欧美日韩在线三级| 中文字幕在线一区| 精品无人码麻豆乱码1区2区| 色呦呦国产精品| 久久天天做天天爱综合色| 亚洲h动漫在线| 91视频91自| 中文字幕成人网| 毛片av一区二区三区| 欧美性生交片4| 亚洲自拍都市欧美小说| 丰满岳乱妇一区二区三区| 欧美v日韩v国产v| 亚洲第一福利一区| 日本精品一级二级| 国产精品不卡一区二区三区| 国产在线播精品第三| 欧美高清激情brazzers| 亚洲黄色尤物视频| av在线这里只有精品| 欧美经典一区二区| 国产精品综合久久| 精品国产乱码久久| 久久国产尿小便嘘嘘| 日韩一区二区视频| 免费一级片91| 51午夜精品国产| 日韩电影一区二区三区四区| 欧美揉bbbbb揉bbbbb| 亚洲黄色尤物视频| 欧美综合在线视频| 亚洲国产美女搞黄色| 欧美日韩一区二区在线视频| 一区二区三区日韩在线观看| 97aⅴ精品视频一二三区| 国产精品久久久久一区二区三区共| 国产一区福利在线| 2021中文字幕一区亚洲| 国产伦精一区二区三区| 国产视频一区二区三区在线观看| 国产一二三精品| 国产精品热久久久久夜色精品三区 | 亚洲女女做受ⅹxx高潮| 97se亚洲国产综合自在线| 国产精品国产精品国产专区不片 | 麻豆久久久久久久| 精品嫩草影院久久| 国产伦精品一区二区三区在线观看| 精品国产一区二区三区忘忧草| 国产一区在线不卡| 国产精品久线在线观看| 色婷婷香蕉在线一区二区| 亚洲宅男天堂在线观看无病毒| 欧美日韩一区 二区 三区 久久精品| 亚洲最色的网站| 337p亚洲精品色噜噜| 久久97超碰色| 亚洲国产高清aⅴ视频| 99久久综合狠狠综合久久| 亚洲视频你懂的| 欧美日韩国产高清一区二区| 麻豆91在线观看| 国产精品第一页第二页第三页| 91麻豆自制传媒国产之光| 亚洲国产aⅴ成人精品无吗| 日韩午夜av一区| 高清国产午夜精品久久久久久| 国产精品超碰97尤物18| 欧美高清一级片在线| 国产麻豆精品一区二区| 亚洲人成小说网站色在线| 在线播放国产精品二区一二区四区|