WebKit Bugzilla
Attachment 349493 Details for
Bug 180731
: Web Inspector: Support for JavaScript BigInt
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
[PATCH] WIP
bigint-1.patch (text/plain), 17.60 KB, created by
Joseph Pecoraro
on 2018-09-11 16:51:44 PDT
(
hide
)
Description:
[PATCH] WIP
Filename:
MIME Type:
Creator:
Joseph Pecoraro
Created:
2018-09-11 16:51:44 PDT
Size:
17.60 KB
patch
obsolete
>diff --git a/Source/JavaScriptCore/inspector/InjectedScriptSource.js b/Source/JavaScriptCore/inspector/InjectedScriptSource.js >index d6b75f1fecd..f41a34524ef 100644 >--- a/Source/JavaScriptCore/inspector/InjectedScriptSource.js >+++ b/Source/JavaScriptCore/inspector/InjectedScriptSource.js >@@ -44,6 +44,8 @@ function toStringDescription(obj) > { > if (obj === 0 && 1 / obj < 0) > return "-0"; >+ if (typeof obj === "bigint") >+ return toString(obj) + "n"; > > return toString(obj); > } >@@ -55,9 +57,14 @@ function isUInt32(obj) > return "" + (obj >>> 0) === obj; > } > >-function isSymbol(obj) >+function isSymbol(value) > { >- return typeof obj === "symbol"; >+ return typeof value === "symbol"; >+} >+ >+function isBigInt(value) >+{ >+ return typeof value === "bigint"; > } > > function isEmptyObject(object) >@@ -427,7 +434,7 @@ let InjectedScript = class InjectedScript > if (isPrimitiveValue(object)) > result.value = object; > else >- result.description = toString(object); >+ result.description = toStringDescription(object); > return result; > } > >@@ -816,7 +823,7 @@ let RemoteObject = class RemoteObject > if (this.type === "undefined" && InjectedScriptHost.isHTMLAllCollection(object)) > this.type = "object"; > >- if (isPrimitiveValue(object) || object === null || forceValueType) { >+ if (isPrimitiveValue(object) || isBigInt(object) || object === null || forceValueType) { > // We don't send undefined values over JSON. > if (this.type !== "undefined") > this.value = object; >@@ -828,6 +835,13 @@ let RemoteObject = class RemoteObject > // Provide user-friendly number values. > if (this.type === "number") > this.description = toStringDescription(object); >+ >+ // BigInt is not JSON serializable. >+ if (this.type === "bigint") { >+ delete this.value; >+ this.description = toStringDescription(object); >+ } >+ > return; > } > >@@ -895,7 +909,7 @@ let RemoteObject = class RemoteObject > if (value === null) > return "null"; > >- if (isPrimitiveValue(value) || isSymbol(value)) >+ if (isPrimitiveValue(value) || isBigInt(value) || isSymbol(value)) > return null; > > if (InjectedScriptHost.isHTMLAllCollection(value)) >@@ -919,6 +933,9 @@ let RemoteObject = class RemoteObject > if (isPrimitiveValue(value)) > return null; > >+ if (isBigInt(value)) >+ return null; >+ > if (isSymbol(value)) > return toString(value); > >@@ -1137,7 +1154,7 @@ let RemoteObject = class RemoteObject > > // Primitive. > const maxLength = 100; >- if (isPrimitiveValue(value)) { >+ if (isPrimitiveValue(value) || isBigInt(value)) { > if (type === "string" && value.length > maxLength) { > value = this._abbreviateString(value, maxLength, true); > preview.lossless = false; >@@ -1255,7 +1272,7 @@ let RemoteObject = class RemoteObject > return false; > > // Primitive. >- if (isPrimitiveValue(object) || isSymbol(object)) >+ if (isPrimitiveValue(object) || isBigInt(object) || isSymbol(object)) > return true; > > // Null. >diff --git a/Source/JavaScriptCore/inspector/protocol/Runtime.json b/Source/JavaScriptCore/inspector/protocol/Runtime.json >index 5f0f40d9bd1..c5ca4ac7f7a 100644 >--- a/Source/JavaScriptCore/inspector/protocol/Runtime.json >+++ b/Source/JavaScriptCore/inspector/protocol/Runtime.json >@@ -13,7 +13,7 @@ > "type": "object", > "description": "Mirror object referencing original JavaScript object.", > "properties": [ >- { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." }, >+ { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "bigint"], "description": "Object type." }, > { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "weakset", "iterator", "class", "proxy"], "description": "Object subtype hint. Specified for <code>object</code> <code>function</code> (for class) type values only." }, > { "name": "className", "type": "string", "optional": true, "description": "Object class (constructor) name. Specified for <code>object</code> type values only." }, > { "name": "value", "type": "any", "optional": true, "description": "Remote object value (in case of primitive values or JSON values if it was requested)." }, >@@ -29,7 +29,7 @@ > "type": "object", > "description": "Object containing abbreviated remote object value.", > "properties": [ >- { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." }, >+ { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "bigint"], "description": "Object type." }, > { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "weakset", "iterator", "class", "proxy"], "description": "Object subtype hint. Specified for <code>object</code> type values only." }, > { "name": "description", "type": "string", "optional": true, "description": "String representation of the object." }, > { "name": "lossless", "type": "boolean", "description": "Determines whether preview is lossless (contains all information of the original object)." }, >@@ -44,7 +44,7 @@ > "type": "object", > "properties": [ > { "name": "name", "type": "string", "description": "Property name." }, >- { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "accessor"], "description": "Object type." }, >+ { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "bigint", "accessor"], "description": "Object type." }, > { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "error", "map", "set", "weakmap", "weakset", "iterator", "class", "proxy"], "description": "Object subtype hint. Specified for <code>object</code> type values only." }, > { "name": "value", "type": "string", "optional": true, "description": "User-friendly property value string." }, > { "name": "valuePreview", "$ref": "ObjectPreview", "optional": true, "description": "Nested value preview." }, >@@ -157,7 +157,8 @@ > { "name": "isNumber", "type": "boolean", "description": "Indicates if this type description has been type Number." }, > { "name": "isString", "type": "boolean", "description": "Indicates if this type description has been type String." }, > { "name": "isObject", "type": "boolean", "description": "Indicates if this type description has been type Object." }, >- { "name": "isSymbol", "type": "boolean", "description": "Indicates if this type description has been type Symbol." } >+ { "name": "isSymbol", "type": "boolean", "description": "Indicates if this type description has been type Symbol." }, >+ { "name": "isBigInt", "type": "boolean", "description": "Indicates if this type description has been type BigInt." } > ] > }, > { >diff --git a/Source/JavaScriptCore/runtime/RuntimeType.cpp b/Source/JavaScriptCore/runtime/RuntimeType.cpp >index 1d68a9de06f..7328765c9c6 100644 >--- a/Source/JavaScriptCore/runtime/RuntimeType.cpp >+++ b/Source/JavaScriptCore/runtime/RuntimeType.cpp >@@ -55,6 +55,8 @@ RuntimeType runtimeTypeForValue(VM& vm, JSValue value) > return TypeFunction; > if (value.isSymbol()) > return TypeSymbol; >+ if (value.isBigInt()) >+ return TypeBigInt; > > return TypeNothing; > } >@@ -77,6 +79,10 @@ String runtimeTypeAsString(RuntimeType type) > return "Boolean"_s; > if (type == TypeFunction) > return "Function"_s; >+ if (type == TypeSymbol) >+ return "Symbol"_s; >+ if (type == TypeBigInt) >+ return "BigInt"_s; > if (type == TypeNothing) > return "(Nothing)"_s; > >diff --git a/Source/JavaScriptCore/runtime/RuntimeType.h b/Source/JavaScriptCore/runtime/RuntimeType.h >index 82388eb0a47..bd446babfca 100644 >--- a/Source/JavaScriptCore/runtime/RuntimeType.h >+++ b/Source/JavaScriptCore/runtime/RuntimeType.h >@@ -40,12 +40,13 @@ enum RuntimeType : uint16_t { > TypeNumber = 0x20, > TypeString = 0x40, > TypeObject = 0x80, >- TypeSymbol = 0x100 >+ TypeSymbol = 0x100, >+ TypeBigInt = 0x200, > }; > > typedef uint16_t RuntimeTypeMask; > >-static const RuntimeTypeMask RuntimeTypeMaskAllTypes = TypeFunction | TypeUndefined | TypeNull | TypeBoolean | TypeAnyInt | TypeNumber | TypeString | TypeObject | TypeSymbol; >+static const RuntimeTypeMask RuntimeTypeMaskAllTypes = TypeFunction | TypeUndefined | TypeNull | TypeBoolean | TypeAnyInt | TypeNumber | TypeString | TypeObject | TypeSymbol | TypeBigInt; > > class JSValue; > RuntimeType runtimeTypeForValue(VM&, JSValue); >diff --git a/Source/JavaScriptCore/runtime/TypeSet.cpp b/Source/JavaScriptCore/runtime/TypeSet.cpp >index ae3102ed052..22035f8a28b 100644 >--- a/Source/JavaScriptCore/runtime/TypeSet.cpp >+++ b/Source/JavaScriptCore/runtime/TypeSet.cpp >@@ -187,6 +187,8 @@ String TypeSet::displayName() const > return "String"_s; > if (doesTypeConformTo(TypeSymbol)) > return "Symbol"_s; >+ if (doesTypeConformTo(TypeBigInt)) >+ return "BigInt"_s; > > if (doesTypeConformTo(TypeNull | TypeUndefined)) > return "(?)"_s; >@@ -203,6 +205,8 @@ String TypeSet::displayName() const > return "String?"_s; > if (doesTypeConformTo(TypeSymbol | TypeNull | TypeUndefined)) > return "Symbol?"_s; >+ if (doesTypeConformTo(TypeBigInt | TypeNull | TypeUndefined)) >+ return "BigInt?"_s; > > if (doesTypeConformTo(TypeObject | TypeFunction | TypeString)) > return "Object"_s; >@@ -239,6 +243,7 @@ Ref<Inspector::Protocol::Runtime::TypeSet> TypeSet::inspectorTypeSet() const > .setIsString((m_seenTypes & TypeString) != TypeNothing) > .setIsObject((m_seenTypes & TypeObject) != TypeNothing) > .setIsSymbol((m_seenTypes & TypeSymbol) != TypeNothing) >+ .setIsBigInt((m_seenTypes & TypeBigInt) != TypeNothing) > .release(); > } > >diff --git a/Source/WebInspectorUI/UserInterface/External/CodeMirror/javascript.js b/Source/WebInspectorUI/UserInterface/External/CodeMirror/javascript.js >index 10419bf9de2..c3f99b0b834 100644 >--- a/Source/WebInspectorUI/UserInterface/External/CodeMirror/javascript.js >+++ b/Source/WebInspectorUI/UserInterface/External/CodeMirror/javascript.js >@@ -112,17 +112,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { > return ret(ch); > } else if (ch == "=" && stream.eat(">")) { > return ret("=>", "operator"); >- } else if (ch == "0" && stream.eat(/x/i)) { >- stream.eatWhile(/[\da-f]/i); >- return ret("number", "number"); >- } else if (ch == "0" && stream.eat(/o/i)) { >- stream.eatWhile(/[0-7]/i); >- return ret("number", "number"); >- } else if (ch == "0" && stream.eat(/b/i)) { >- stream.eatWhile(/[01]/i); >+ } else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) { > return ret("number", "number"); > } else if (/\d/.test(ch)) { >- stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); >+ stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/); > return ret("number", "number"); > } else if (ch == "/") { > if (stream.eat("*")) { >diff --git a/Source/WebInspectorUI/UserInterface/Models/TypeSet.js b/Source/WebInspectorUI/UserInterface/Models/TypeSet.js >index 4429f42e35f..3631c06f935 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/TypeSet.js >+++ b/Source/WebInspectorUI/UserInterface/Models/TypeSet.js >@@ -49,6 +49,8 @@ WI.TypeSet = class TypeSet > bitString |= WI.TypeSet.TypeBit.Object; > if (typeSet.isSymbol) > bitString |= WI.TypeSet.TypeBit.Symbol; >+ if (typeSet.isBigInt) >+ bitString |= WI.TypeSet.TypeBit.BigInt; > console.assert(bitString); > > this._typeSet = typeSet; >@@ -102,6 +104,8 @@ WI.TypeSet = class TypeSet > this._primitiveTypeNames.push("String"); > if (typeSet.isSymbol) > this._primitiveTypeNames.push("Symbol"); >+ if (typeSet.isBigInt) >+ this._primitiveTypeNames.push("BigInt"); > > // It's implied that type Integer is contained in type Number. Don't put > // both 'Integer' and 'Number' into the set because this could imply that >@@ -124,7 +128,8 @@ WI.TypeSet.TypeBit = { > "Number" : 0x20, > "String" : 0x40, > "Object" : 0x80, >- "Symbol" : 0x100 >+ "Symbol" : 0x100, >+ "BigInt" : 0x200, > }; > > WI.TypeSet.NullOrUndefinedTypeBits = WI.TypeSet.TypeBit.Null | WI.TypeSet.TypeBit.Undefined; >diff --git a/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js b/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js >index 3491166e69e..3762293f57a 100644 >--- a/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js >+++ b/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js >@@ -59,13 +59,19 @@ WI.RemoteObject = class RemoteObject > this._description = "class " + className; > } > } else { >- // Primitive or null. >+ // Primitive, BigInt, or null. > console.assert(type !== "object" || value === null); > console.assert(!preview); > > this._description = description || (value + ""); > this._hasChildren = false; > this._value = value; >+ >+ if (type === "bigint") { >+ console.assert(value === undefined); >+ console.assert(description.endsWith("n")); >+ this._value = BigInt(description.substring(0, description.length - 1)); >+ } > } > } > >diff --git a/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css b/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css >index 920e870675d..c0083cf5fc5 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css >+++ b/Source/WebInspectorUI/UserInterface/Views/FormattedValue.css >@@ -58,6 +58,10 @@ > color: var(--syntax-highlight-symbol-color); > } > >+.formatted-bigint { >+ color: var(--syntax-highlight-bigint-color); >+} >+ > .formatted-null, .formatted-undefined { > color: hsl(0, 0%, 50%); > } >diff --git a/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.css b/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.css >index 003b3a41319..1a45c186fd5 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.css >+++ b/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.css >@@ -59,6 +59,10 @@ > background-color: var(--syntax-highlight-symbol-color); > } > >+.type-token-bigint { >+ background-color: var(--syntax-highlight-bigint-color); >+} >+ > .type-token-default { > background-color: hsl(83, 71%, 39%); > } >diff --git a/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.js b/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.js >index b351638f353..1600af071b3 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.js >+++ b/Source/WebInspectorUI/UserInterface/Views/TypeTokenView.js >@@ -160,6 +160,8 @@ WI.TypeTokenView = class TypeTokenView extends WI.Object > return "String"; > if (typeSet.isContainedIn(WI.TypeSet.TypeBit.Symbol)) > return "Symbol"; >+ if (typeSet.isContainedIn(WI.TypeSet.TypeBit.BigInt)) >+ return "BigInt"; > > if (typeSet.isContainedIn(WI.TypeSet.NullOrUndefinedTypeBits)) > return "(?)"; >@@ -176,6 +178,8 @@ WI.TypeTokenView = class TypeTokenView extends WI.Object > return "String?"; > if (typeSet.isContainedIn(WI.TypeSet.TypeBit.Symbol | WI.TypeSet.NullOrUndefinedTypeBits)) > return "Symbol?"; >+ if (typeSet.isContainedIn(WI.TypeSet.TypeBit.BigInt | WI.TypeSet.NullOrUndefinedTypeBits)) >+ return "BigInt?"; > > if (typeSet.isContainedIn(WI.TypeSet.TypeBit.Object | WI.TypeSet.TypeBit.Function | WI.TypeSet.TypeBit.String)) > return "Object"; >@@ -194,6 +198,7 @@ WI.TypeTokenView.TitleType = { > WI.TypeTokenView.ColorClassForType = { > "String": "type-token-string", > "Symbol": "type-token-symbol", >+ "BigInt": "type-token-bigint", > "Function": "type-token-function", > "Number": "type-token-number", > "Integer": "type-token-number", >diff --git a/Source/WebInspectorUI/UserInterface/Views/Variables.css b/Source/WebInspectorUI/UserInterface/Views/Variables.css >index 288372c9783..f30368532f4 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/Variables.css >+++ b/Source/WebInspectorUI/UserInterface/Views/Variables.css >@@ -82,6 +82,7 @@ > --breakpoint-unresolved-disabled-stroke-color: hsl(0, 0%, 78%); > > --syntax-highlight-number-color: hsl(248, 100%, 40%); >+ --syntax-highlight-bigint-color: var(--syntax-highlight-number-color); > --syntax-highlight-boolean-color: hsl(309, 85%, 35%); > --syntax-highlight-string-color: hsl(1, 79%, 42%); > --syntax-highlight-link-color: hsl(240, 100%, 52%);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 180731
:
349493
|
376476
|
376477
|
376478
|
376479
|
376480
|
376538
|
376578
|
376579
|
376580
|
376703