V8 typeof null return "undefined" bug what's going on

Source: Internet
Author: User

In 1997, IE 4.0 was released, bringing a number of new features to the future "far-reaching" DOM API:document.all. In the next 6 years, IE's market share is increasing, until 2003 of 95%.

During this time, two thousands of pages were produced. The first: IE only page, because of the ultra-high market share, developers feel that there is no need to consider compatibility, so direct use of document.all, such as:

document.all (foo). style.visibility = "visible"

Even many sites directly on the server side to determine the client UA, not IE directly return a word: "This site only support IE ... ”

Second page: Developers use document.all to identify IE, only to show special effects on IE:

var isie =!! document.all if (Isie) {  //  using the IE private DOM API, private CSS features }

Many of the books of that time were also talking about this method of judging, until now, in 2016, it is estimated that a few people wrote this, and the domestic publication of the book of rubbish is likely to copy and paste the code elsewhere.

Due to the large presence of the first page, opera in 2002 released the 6.0 version of the implementation of document.all, which led to the result is that the first IE only page can be viewed in Opera normal, this is good news, but the bad news is that the second page instead of error Out,!! Document.all is true, opera is considered ie, opera cannot support all the private features of IE. There were a lot of people who gave Opera feedback bugs and developers said they couldn't fix them.

During this time, in order to seize the market share, Mozilla's people are also continuing to discuss the implementation of Document.all,bugzilla there are many historical posts to check. Finally, in 2004, the father of JavaScript Brendan Eich in the Firefox 0.10 preview version of the implementation of document.all, but with Opera's warning, Brendan in the implementation of Document.all played a The trick is that you can use document.all normally, but you can't detect its presence:

typeof document.all"undefined" >!! document.all false

Brendan named "undetected Document.all", but at that time many people also found that document.all is not really detected, such as:

> document.all = = = undefinedfalse in documenttrue

At that time Mozilla's people also replied: "This is not a bug, because this change is forced, and this change is violated ECMASCIRPT specification, the smaller the better, in and = = = Not to tube, after all, very few people with the = = = and in judging document.all exist Or not. " This is the implementation of all browsers today, as is the case in the HTML 5 specification.

That period of time Safari just started, but also received from the user does not support document.all bug,2005 end, Safari learning Firefox, realized the undetectable document.all.

In 2008, opera in the 9.50 Beta 2 version of its direct exposure to the years of document.all also changed to undetectable, the change is written in the record: "Opera now Cloaks document.all". Opera's engineers also wrote an article about Document.all's changes in opera, and said that document.all is definitely worth being exhibited in the Web Technology Museum.

At the end of 2008, Chrome 1.0 was released, and Chrome was based on Webkit and V8, V8 of course with document.all in Webkit.

Quite dramatically, in 2013, even IE itself (ie 11) also hid the document.all, that is, all modern browsers document.all is a false value.

The implementation in V8 is that an object can be labeled as undetectable, and for many years only document.all has this tag, which is the relevant code snippet and comment:

 //  tells whether the instance is Undetectable.  //  undetectable object is a special class of jsobject: ' typeof ' operator  //  returns undefined, ToBoolean returns false. Otherwise it behaves like  //  a normal JS  Object. It is useful for implementing undetectable  //  document.all in Firefox & Safari.  //  see https://bugzilla.mozilla.org/show_bug.cgi?id=248549.  inline void   set_is_undetectable (); inline bool Is_undetectable ();  

Then, in the typeof implementation, if the typeof parameter is undefined or undetectable, it returns "undefined":

Handle<string> object::typeof (isolate* Isolate, handle<object>Object) {  if(Object->isnumber ())returnIsolate->factory ()number_string ();  If (object->isundefined () | | | Object, Isundetectableobject ()) { returnIsolate->factory ()undefined_string (); }  if(Object->isboolean ())returnIsolate->factory ()boolean_string (); if(Object->isstring ())returnIsolate->factory ()string_string (); if(Object->issymbol ())returnIsolate->factory ()symbol_string (); if(Object->isstring ())returnIsolate->factory ()string_string ();#defineSimd128_type (type, type, type, Lane_count, Lane_type)if(Object->is# #Type ())returnIsolate->factory ()type# #_string (); Simd128_types (Simd128_type)#undefSimd128_typeif(Object->iscallable ())returnIsolate->factory ()function_string (); returnIsolate->factory ()object_string ();}

This February, V8 made a change, that is, in addition to document.all, the null and undefined two values are also marked as undetectable. At that time, the developer knew clearly that this change would let typeof null return "undefined", so specifically changed the implementation of TypeOf, and added a corresponding test file:

Assertfalse (typeofnull"undefined")

It looks perfect, but in fact the change produced a bug that later streamed to the stable version of 50 and 51.

In April, someone found this bug, refining the repro code is:

 for (Let n = 0; n < 10000; n++) {  console.log (typeofnull = = "undefined")}

The results of the implementation in Chrome are as follows:

After the For loop executes several times, typeof null changes from "object" to "undefined".

I was also concerned about the bug, which was fixed in less than a week's time. At that time, the master branch was Chrome 52, and the developer felt that the bug had little impact (my guess) and did not fit into the stable version of Chrome 50.

In fact, the cause of this bug is: V8 also has an optimization compiler (optimizing compiler), called crankshaft, when the code is executed enough times, JavaScript code will be recompiled by this compiler to execute. The crankshaft has a typeof implementation that it uses alone, unlike the ordinary compilers:

string* typeofstring (hconstant* constant, isolate*isolate) {Heap* Heap = isolate->Heap (); if(Constant->hasnumbervalue ())returnHeap->number_string ();  If (constant->isundetectable ()) return heap->undefined_string (); if(Constant->hasstringvalue ())returnHeap->string_string (); Switch(constant->Getinstancetype ()) {     Caseoddball_type: {Unique<Object> unique = constant->Getunique (); if(Unique. Isknownglobal (Heap->true_value ()) | |unique. Isknownglobal (Heap-False_value ())) {        returnHeap->boolean_string (); }      if(Unique. Isknownglobal (heap->Null_value ())) {        returnHeap->object_string (); } dcheck (unique. Isknownglobal (Heap-Undefined_value ())); returnHeap->undefined_string (); }     CaseSymbol_type:returnHeap->symbol_string ();  Casesimd128_value_type: {Unique<Map> Map = constant->Objectmap (); #define SIMD128_TYPE (type, type, type, Lane_count, Lane_type)if(Map. Isknownglobal (heap->type# #_map ())) {                    returnHeap->type# #_string ();      } simd128_types (Simd128_type) #undef simd128_type unreachable (); returnnullptr; }    default:      if(Constant->iscallable ())returnHeap->function_string (); returnHeap->object_string (); }}

The change developers leaked this typeof implementation, resulting in the above bug, repair is very simple, that is, the red sentence of the judge moved below, while the person fixing the bug specifically added a test file, inside%optimizefunctiononnextcall () is a special function, Allows a function to be compiled directly into the crankshaft to execute.

June 8, the bug was another feedback, said their system because the bug can not be run, ask when the repair code can be in the stable version, there was no response from the relevant personnel.

June 20, someone on the Reddit public this bug, was repeatedly transferred to Twitter, the bug has more people reply.

Chrome's developers realised the problem was a bit serious and cherry-pick the previous commit into Chrome 51.

After this, there are three people who do not know that the bug has been fixed to the repeated bug,issue 621887,issue 622628,issue 5146.

V8 typeof null return "undefined" bug what's going on

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.