Title: [183575] trunk/Source
Revision
183575
Author
[email protected]
Date
2015-04-29 14:27:48 -0700 (Wed, 29 Apr 2015)

Log Message

Source/_javascript_Core:
JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden
https://bugs.webkit.org/show_bug.cgi?id=144397

Reviewed by Andreas Kling.
        
Add the flag to JSTypeInfo. It's an inline flag so that it's fast to query. Slap the flag on
callback objects and internal functions. Modify the TypeOf operation to use this flag to avoid
making a getCallData() call if it isn't necessary.

* API/JSCallbackObject.h:
* runtime/InternalFunction.h:
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::typeOfShouldCallGetCallData):
* runtime/Operations.cpp:
(JSC::jsTypeStringForValue):
* tests/stress/type-of-functions-and-objects.js: Added.
(foo):
(bar):
(baz):
(fuzz):
(expect):
(test):

Source/WebCore:
JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden
https://bugs.webkit.org/show_bug.cgi?id=144397

Reviewed by Andreas Kling.

If you override getCallData() and you want to be called a "function", then you need to use the
new TypeOfShouldCallGetCallData flag.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
* bridge/objc/objc_runtime.h:
* bridge/runtime_method.h:
* bridge/runtime_object.h:

Source/WebKit2:
JSTypeInfo should have an inline type flag to indicate if getCallData() has been overridden
https://bugs.webkit.org/show_bug.cgi?id=144397

Reviewed by Andreas Kling.

If you override getCallData() and you want to be called a "function", then you need to use the
new TypeOfShouldCallGetCallData flag.

* WebProcess/Plugins/Netscape/JSNPObject.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSCallbackObject.h (183574 => 183575)


--- trunk/Source/_javascript_Core/API/JSCallbackObject.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/_javascript_Core/API/JSCallbackObject.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -125,7 +125,7 @@
 
 public:
     typedef Parent Base;
-    static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesGetPropertyNames;
+    static const unsigned StructureFlags = Base::StructureFlags | ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | ImplementsHasInstance | OverridesHasInstance | OverridesGetPropertyNames | TypeOfShouldCallGetCallData;
 
     ~JSCallbackObject();
 

Modified: trunk/Source/_javascript_Core/ChangeLog (183574 => 183575)


--- trunk/Source/_javascript_Core/ChangeLog	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-04-29 21:27:48 UTC (rev 183575)
@@ -1,3 +1,28 @@
+2015-04-29  Filip Pizlo  <[email protected]>
+
+        JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden
+        https://bugs.webkit.org/show_bug.cgi?id=144397
+
+        Reviewed by Andreas Kling.
+        
+        Add the flag to JSTypeInfo. It's an inline flag so that it's fast to query. Slap the flag on
+        callback objects and internal functions. Modify the TypeOf operation to use this flag to avoid
+        making a getCallData() call if it isn't necessary.
+
+        * API/JSCallbackObject.h:
+        * runtime/InternalFunction.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::typeOfShouldCallGetCallData):
+        * runtime/Operations.cpp:
+        (JSC::jsTypeStringForValue):
+        * tests/stress/type-of-functions-and-objects.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        (fuzz):
+        (expect):
+        (test):
+
 2015-04-28  Geoffrey Garen  <[email protected]>
 
         It shouldn't take 1846 lines of code and 5 FIXMEs to sort an array.

Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.h (183574 => 183575)


--- trunk/Source/_javascript_Core/runtime/InternalFunction.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -34,7 +34,7 @@
 class InternalFunction : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
-    static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance;
+    static const unsigned StructureFlags = Base::StructureFlags | ImplementsHasInstance | TypeOfShouldCallGetCallData;
 
     DECLARE_EXPORT_INFO;
 

Modified: trunk/Source/_javascript_Core/runtime/JSTypeInfo.h (183574 => 183575)


--- trunk/Source/_javascript_Core/runtime/JSTypeInfo.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/_javascript_Core/runtime/JSTypeInfo.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -40,6 +40,7 @@
 static const unsigned ImplementsHasInstance = 1 << 1;
 static const unsigned OverridesHasInstance = 1 << 2;
 static const unsigned ImplementsDefaultHasInstance = 1 << 3;
+static const unsigned TypeOfShouldCallGetCallData = 1 << 4; // Need this flag if you override getCallData() and you want typeof to use this to determine if it should say "function". Currently we always set this flag when we override getCallData().
 static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
 static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
 static const unsigned StructureIsImmortal = 1 << 7;
@@ -83,6 +84,7 @@
     bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
     bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance); }
     bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
+    bool typeOfShouldCallGetCallData() const { return isSetOnFlags1(TypeOfShouldCallGetCallData); }
     bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
     static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
     bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }

Modified: trunk/Source/_javascript_Core/runtime/Operations.cpp (183574 => 183575)


--- trunk/Source/_javascript_Core/runtime/Operations.cpp	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/_javascript_Core/runtime/Operations.cpp	2015-04-29 21:27:48 UTC (rev 183575)
@@ -68,14 +68,19 @@
     if (v.isSymbol())
         return vm.smallStrings.symbolString();
     if (v.isObject()) {
+        JSObject* object = asObject(v);
         // Return "undefined" for objects that should be treated
         // as null when doing comparisons.
-        if (asObject(v)->structure(vm)->masqueradesAsUndefined(globalObject))
+        if (object->structure(vm)->masqueradesAsUndefined(globalObject))
             return vm.smallStrings.undefinedString();
-        CallData callData;
-        JSObject* object = asObject(v);
-        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+        if (object->type() == JSFunctionType)
             return vm.smallStrings.functionString();
+        if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
+            CallData callData;
+            JSObject* object = asObject(v);
+            if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+                return vm.smallStrings.functionString();
+        }
     }
     return vm.smallStrings.objectString();
 }

Added: trunk/Source/_javascript_Core/tests/stress/type-of-functions-and-objects.js (0 => 183575)


--- trunk/Source/_javascript_Core/tests/stress/type-of-functions-and-objects.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/type-of-functions-and-objects.js	2015-04-29 21:27:48 UTC (rev 183575)
@@ -0,0 +1,73 @@
+function foo(v) {
+    return typeof v;
+}
+
+function bar(v) {
+    switch (typeof v) {
+    case "object":
+        return 1;
+    case "function":
+        return 2;
+    default:
+        return 3;
+    }
+}
+
+function baz(v) {
+    return typeof v == "function";
+}
+
+function fuzz(v) {
+    return typeof v == "object";
+}
+
+noInline(foo);
+noInline(bar);
+noInline(baz);
+noInline(fuzz);
+
+function expect(f, v, expected) {
+    var result = f(v);
+    if (result != expected)
+        throw "Error: " + f.name + "(" + v + ") returned " + result + " instead of " + expected;
+}
+
+function test(v, expected) {
+    switch (expected) {
+    case "function":
+        expect(foo, v, "function");
+        expect(bar, v, 2);
+        expect(baz, v, true);
+        expect(fuzz, v, false);
+        break;
+    case "object":
+        expect(foo, v, "object");
+        expect(bar, v, 1);
+        expect(baz, v, false);
+        expect(fuzz, v, true);
+        break;
+    case "other":
+        var result = foo(v);
+        if (result == "object" || result == "function")
+            throw "Error: foo(" + v + ") returned " + result + " but expected something other than object or function";
+        expect(bar, v, 3);
+        expect(baz, v, false);
+        expect(fuzz, v, false);
+        break;
+    default:
+        throw "Bad expected case";
+    }
+}
+
+for (var i = 0; i < 10000; ++i) {
+    test({}, "object");
+    test(function() { }, "function");
+    test("hello", "other");
+    test(42, "other");
+    test(null, "object");
+    test(void 0, "other");
+    test(42.5, "other");
+    test(Map, "function");
+    test(Date, "function");
+    test(Map.prototype, "object");
+}

Modified: trunk/Source/WebCore/ChangeLog (183574 => 183575)


--- trunk/Source/WebCore/ChangeLog	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebCore/ChangeLog	2015-04-29 21:27:48 UTC (rev 183575)
@@ -1,3 +1,19 @@
+2015-04-29  Filip Pizlo  <[email protected]>
+
+        JSTypeInfo should have an inline type flag to indicate of getCallData() has been overridden
+        https://bugs.webkit.org/show_bug.cgi?id=144397
+
+        Reviewed by Andreas Kling.
+
+        If you override getCallData() and you want to be called a "function", then you need to use the
+        new TypeOfShouldCallGetCallData flag.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeader):
+        * bridge/objc/objc_runtime.h:
+        * bridge/runtime_method.h:
+        * bridge/runtime_object.h:
+
 2015-04-29  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r183553 and r183561.

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (183574 => 183575)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2015-04-29 21:27:48 UTC (rev 183575)
@@ -900,6 +900,9 @@
     if ($interface->extendedAttributes->{"NewImpurePropertyFiresWatchpoints"}) {
         $structureFlags{"JSC::NewImpurePropertyFiresWatchpoints"} = 1;
     }
+    if ($interface->extendedAttributes->{"CustomCall"}) {
+        $structureFlags{"JSC::TypeOfShouldCallGetCallData"} = 1;
+    }
 
     # Getters
     if ($hasGetter) {

Modified: trunk/Source/WebCore/bridge/objc/objc_runtime.h (183574 => 183575)


--- trunk/Source/WebCore/bridge/objc/objc_runtime.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebCore/bridge/objc/objc_runtime.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -93,7 +93,7 @@
 class ObjcFallbackObjectImp : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | TypeOfShouldCallGetCallData;
 
     static ObjcFallbackObjectImp* create(ExecState* exec, JSGlobalObject* globalObject, ObjcInstance* instance, const String& propertyName)
     {

Modified: trunk/Source/WebCore/bridge/runtime_method.h (183574 => 183575)


--- trunk/Source/WebCore/bridge/runtime_method.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebCore/bridge/runtime_method.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -35,7 +35,7 @@
 class WEBCORE_EXPORT RuntimeMethod : public InternalFunction {
 public:
     typedef InternalFunction Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | TypeOfShouldCallGetCallData;
 
     static RuntimeMethod* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const String& name, Bindings::Method* method)
     {

Modified: trunk/Source/WebCore/bridge/runtime_object.h (183574 => 183575)


--- trunk/Source/WebCore/bridge/runtime_object.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebCore/bridge/runtime_object.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -35,7 +35,7 @@
 class WEBCORE_EXPORT RuntimeObject : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | TypeOfShouldCallGetCallData;
 
     static RuntimeObject* create(VM& vm, Structure* structure, PassRefPtr<Instance> instance)
     {

Modified: trunk/Source/WebKit2/ChangeLog (183574 => 183575)


--- trunk/Source/WebKit2/ChangeLog	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebKit2/ChangeLog	2015-04-29 21:27:48 UTC (rev 183575)
@@ -1,3 +1,15 @@
+2015-04-29  Filip Pizlo  <[email protected]>
+
+        JSTypeInfo should have an inline type flag to indicate if getCallData() has been overridden
+        https://bugs.webkit.org/show_bug.cgi?id=144397
+
+        Reviewed by Andreas Kling.
+
+        If you override getCallData() and you want to be called a "function", then you need to use the
+        new TypeOfShouldCallGetCallData flag.
+
+        * WebProcess/Plugins/Netscape/JSNPObject.h:
+
 2015-04-29  Antti Koivisto  <[email protected]>
 
         ResourceLoadPriority should be enum class

Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h (183574 => 183575)


--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h	2015-04-29 20:50:29 UTC (rev 183574)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h	2015-04-29 21:27:48 UTC (rev 183575)
@@ -44,7 +44,7 @@
 class JSNPObject : public JSC::JSDestructibleObject {
 public:
     typedef JSC::JSDestructibleObject Base;
-    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames;
+    static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSC::TypeOfShouldCallGetCallData;
 
     static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject)
     {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to