Commit e2fe4ceb authored by oliver@apple.com's avatar oliver@apple.com

fourthTier: Rationalized 'this' conversion, includes subsequent FTL branch fixes

Reviewed by Oliver Hunt.

Source/JavaScriptCore:

    Rationalized 'this' value conversion
    https://bugs.webkit.org/show_bug.cgi?id=115542

    This fixes a bunch of Sputnik tests, and some bad pointer access.

    The new model is that the callee always performs 'this' value conversion.

    My ultimate goal is to break up resolve_with_this into single-result
    opcodes. This step avoids having to add a special form of convert_this
    that distinguishes callers vs callees.

    Only the callee knows whether it uses 'this' and/or whether 'this'
    conversion should use StrictMode, so it's most natural to perform
    convert_this in the callee.

    * API/JSCallbackFunction.cpp:
    (JSC::JSCallbackFunction::call): Perform 'this' value conversion for
    our callee, since it may observe 'this'.

    * API/JSCallbackObjectFunctions.h:
    (JSC::::call): Ditto.

    * API/JSContextRef.cpp:
    (JSGlobalContextCreateInGroup): Use a proxy 'this' object in global scope
    even when we're not in the browser. This eliminates some odd cases where
    API clients used to be able to get a direct reference to an environment
    record. Now, any reference to an environment record unambiguously means
    that the VM resolved that record in the scope chain.

    (JSContextGetGlobalObject): Removed an incorrect comment. Now that JSC
    participates in the proxy 'this' object scheme, the behavior is not
    WebCore-only.

    * API/JSObjectRef.cpp:
    (JSObjectSetPrototype):
    (JSObjectCallAsFunction): Don't perform 'this' value conversion in the
    caller; the callee will do it if needed.

    * JavaScriptCore.order: Order!

    * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
    * JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
    What are the chances that this will work?

    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::dumpBytecode):
    (JSC::CodeBlock::CodeBlock): Renamed convert_this to to_this, to match our
    other conversion opcodes.

    * bytecode/CodeOrigin.h:
    (CodeOrigin):
    (InlineCallFrame):
    (JSC::CodeOrigin::codeOriginOwner): Use the more precise type for our
    executable, so compilation can discover where we're in strict mode.

    * bytecode/Opcode.h:
    (JSC::padOpcodeName): Updated for rename.

    * bytecompiler/BytecodeGenerator.cpp:
    (JSC::BytecodeGenerator::BytecodeGenerator): Always emit to_this when
    'this' is in use -- strict mode still needs to convert environment
    records to 'undefined'.

    * dfg/DFGAbstractState.cpp:
    (JSC::DFG::AbstractState::executeEffects):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::parseBlock):
    * dfg/DFGCapabilities.h:
    (JSC::DFG::canCompileOpcode): Updated for renames.

    * dfg/DFGFixupPhase.cpp:
    (JSC::DFG::FixupPhase::fixupNode): Tightened up this code to consider
    strict mode (a new requirement) and to consider the global object (which
    was always a requirement).

    * dfg/DFGGraph.h:
    (JSC::DFG::Graph::globalThisObjectFor):
    (JSC::DFG::Graph::executableFor):
    * dfg/DFGNodeType.h:
    * dfg/DFGOperations.cpp:
    * dfg/DFGOperations.h:
    * dfg/DFGPredictionPropagationPhase.cpp:
    (JSC::DFG::PredictionPropagationPhase::propagate):
    * dfg/DFGSpeculativeJIT32_64.cpp:
    (JSC::DFG::SpeculativeJIT::compile):
    * dfg/DFGSpeculativeJIT64.cpp:
    (JSC::DFG::SpeculativeJIT::compile): Ditto.

    * interpreter/Interpreter.cpp:
    (JSC::eval):
    (JSC::Interpreter::execute):
    (JSC::Interpreter::executeCall):
    * interpreter/Interpreter.h: Don't ASSERT about 'this' -- it's our job
    to fix it up if needed.

    * jit/JIT.cpp:
    (JSC::JIT::privateCompileMainPass):
    (JSC::JIT::privateCompileSlowCases):
    * jit/JIT.h:
    (JIT):
    * jit/JITOpcodes.cpp:
    (JSC::JIT::emit_op_to_this):
    (JSC::JIT::emitSlow_op_to_this):
    * jit/JITOpcodes32_64.cpp:
    (JSC::JIT::emit_op_to_this):
    (JSC::JIT::emitSlow_op_to_this):
    * jit/JITStubs.cpp:
    (JSC::DEFINE_STUB_FUNCTION):
    * jit/JITStubs.h: Removed special-case code for various kinds of
    conversions. The baseline fast path is now final objects only. It hurt
    my brain to think through how to keep the other fast paths working, and
    our benchmarks do not object.

    * llint/LLIntData.cpp:
    (JSC::LLInt::Data::performAssertions):
    * llint/LLIntSlowPaths.cpp:
    (JSC::LLInt::LLINT_SLOW_PATH_DECL):
    * llint/LLIntSlowPaths.h:
    (LLInt):
    * llint/LowLevelInterpreter.asm:
    * llint/LowLevelInterpreter32_64.asm:
    * llint/LowLevelInterpreter64.asm: Updated for renames. Removed some
    special case code, as in the JIT above.

    * profiler/ProfileGenerator.cpp:
    (JSC::ProfileGenerator::addParentForConsoleStart):
    * runtime/CallData.cpp:
    (JSC::call):
    * runtime/ClassInfo.h:
    (MethodTable):
    * runtime/Completion.cpp:
    (JSC::evaluate):
    * runtime/DatePrototype.cpp:
    (JSC::dateProtoFuncToJSON): The callee performs 'this' conversion, not
    the caller.

    * runtime/GetterSetter.cpp:
    (JSC::callGetter):
    (JSC::callSetter):
    * runtime/GetterSetter.h: Added helper functions for invoking getters
    and setters from C++ code, since this was duplicated in a bunch of
    places.

    * runtime/JSActivation.cpp:
    (JSC::JSActivation::toThis):
    * runtime/JSActivation.h:
    (JSActivation):
    * runtime/JSCJSValue.cpp:
    (JSC::JSValue::toThisSlowCase):
    (JSC::JSValue::putToPrimitive):
    * runtime/JSCJSValue.h:
    (JSValue):
    * runtime/JSCJSValueInlines.h:
    (JSC::JSValue::toThis):
    * runtime/JSCell.cpp:
    (JSC::JSCell::toThis):
    * runtime/JSCell.h:
    (JSCell):
    * runtime/JSGlobalObject.cpp:
    (JSC::JSGlobalObject::toThis):
    * runtime/JSGlobalObject.h:
    (JSGlobalObject): Filled out runtime support for converting 'this'
    values as needed, according to the appropriate strictness, using
    helper functions where getter/setter code was duplicated.

    * runtime/JSGlobalObjectFunctions.cpp:
    (JSC::globalFuncProtoGetter):
    (JSC::globalFuncProtoSetter): Perform 'this' value conversion, since we
    observe 'this'.

    * runtime/JSNameScope.cpp:
    (JSC::JSNameScope::toThis):
    * runtime/JSNameScope.h:
    (JSNameScope): Same as JSActivation.

    * runtime/JSObject.cpp:
    (JSC::JSObject::put):
    (JSC::JSObject::setPrototypeWithCycleCheck): Bug fix. Don't peform
    'this' value conversion in this helper function. The __proto__
    setter does this for us, since it's the function that logically observes
    'this' -- and we can ASSERT so. Also, the previous code used
    "globalExec()->thisValue()", which is a read past the beginning of a
    buffer! I don't think this ever worked on purpose.

    (JSC::JSObject::toThis):
    (JSC::JSObject::fillGetterPropertySlot):
    * runtime/JSObject.h:
    (JSC::JSObject::inlineGetOwnPropertySlot):
    * runtime/JSScope.cpp:
    (JSC::JSScope::resolveWithThis):
    * runtime/JSString.cpp:
    (JSC::JSString::toThis):
    * runtime/JSString.h:
    (JSString):
    * runtime/PropertySlot.cpp:
    (JSC::PropertySlot::functionGetter):
    * runtime/PropertySlot.h:
    (JSC):
    (JSC::PropertySlot::setGetterSlot):
    (JSC::PropertySlot::setCacheableGetterSlot):
    * runtime/SparseArrayValueMap.cpp:
    (JSC::SparseArrayEntry::get):
    (JSC::SparseArrayEntry::put):
    * runtime/StrictEvalActivation.cpp:
    (JSC::StrictEvalActivation::toThis):
    * runtime/StrictEvalActivation.h:
    (StrictEvalActivation): Ditto.

Source/WebCore:

    Rationalized 'this' value conversion
    https://bugs.webkit.org/show_bug.cgi?id=115542

Source/WebKit/mac:

    Rationalized 'this' value conversion
    https://bugs.webkit.org/show_bug.cgi?id=115542

Source/WebKit2:

    Rationalized 'this' value conversion
    https://bugs.webkit.org/show_bug.cgi?id=115542

LayoutTests:

    Rationalized 'this' value conversion
    https://bugs.webkit.org/show_bug.cgi?id=115542

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153145 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e571c18d
2013-05-05 Geoffrey Garen <ggaren@apple.com>
Rolled back in r149527 with crash fixed.
Reviewed by Oliver Hunt.
Rationalized 'this' value conversion
https://bugs.webkit.org/show_bug.cgi?id=115542
2013-04-03 Filip Pizlo <fpizlo@apple.com>
fourthTier: Just linking LLVM into JSC causes all plugin tests to fail
......@@ -99,11 +99,11 @@ PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined, set:
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {set:function(x){this.result = x;}}); o.foo is undefined
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {set:function(x){this.result = x;}}); o.foo = 42; o.result; is 42
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}, set:undefined}); o.foo is 42
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}, set:undefined}); o.foo = 42; o.result; threw exception TypeError: setting a property that has only a getter.
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}, set:undefined}); o.foo = 42; o.result; threw exception TypeError: Attempted to assign to readonly property..
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}}); o.foo is 42
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}}); o.foo = 42; o.result; threw exception TypeError: setting a property that has only a getter.
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:function(){return 42;}}); o.foo = 42; o.result; threw exception TypeError: Attempted to assign to readonly property..
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined, set:undefined}); o.foo is undefined
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined, set:undefined}); o.foo = 42; o.result; threw exception TypeError: setting a property that has only a getter.
PASS 'use strict'; var o = Object.defineProperty({}, 'foo', {get:undefined, set:undefined}); o.foo = 42; o.result; threw exception TypeError: Attempted to assign to readonly property..
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:function(){return 13;}}); o.foo is 13
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:function(){return 13;}}); o.foo = 42; o.result; is 42
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {get:undefined}); o.foo is undefined
......@@ -111,7 +111,7 @@ PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1},
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:function(){this.result = 13;}}); o.foo is 42
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:function(){this.result = 13;}}); o.foo = 42; o.result; is 13
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:undefined}); o.foo is 42
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:undefined}); o.foo = 42; o.result; threw exception TypeError: setting a property that has only a getter.
PASS 'use strict'; var o = Object.defineProperty(Object.defineProperty({foo:1}, 'foo', {get:function(){return 42;}, set:function(x){this.result = x;}}), 'foo', {set:undefined}); o.foo = 42; o.result; threw exception TypeError: Attempted to assign to readonly property..
PASS 0 in Object.prototype is true
PASS '0' in Object.prototype is true
PASS var o = {}; o.readOnly = false; o.readOnly is true
......
S11.1.1_A2
FAIL SputnikError: #1: this.toString() === toString(). Actual: [object Window]
PASS
TEST COMPLETE
......@@ -67,7 +67,7 @@ EncodedJSValue JSCallbackFunction::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->hostThisValue().toThis(exec, NotStrictMode)));
size_t argumentCount = exec->argumentCount();
Vector<JSValueRef, 16> arguments;
......
......@@ -490,7 +490,7 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(exec->callee());
JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->hostThisValue().toThis(exec, NotStrictMode)));
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
......
......@@ -135,6 +135,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
if (!globalObjectClass) {
JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));
globalObject->setGlobalThis(*vm, JSProxy::create(*vm, JSProxy::createStructure(*vm, globalObject, globalObject->prototype()), globalObject));
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
......@@ -186,8 +187,7 @@ JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
ExecState* exec = toJS(ctx);
APIEntryShim entryShim(exec);
// It is necessary to call toThisObject to get the wrapper object when used with WebCore.
return toRef(exec->lexicalGlobalObject()->methodTable()->toThisObject(exec->lexicalGlobalObject(), exec));
return toRef(jsCast<JSObject*>(exec->lexicalGlobalObject()->methodTable()->toThis(exec->lexicalGlobalObject(), exec, NotStrictMode)));
}
JSContextGroupRef JSContextGetGroup(JSContextRef ctx)
......
......@@ -277,7 +277,7 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
jsObject->setPrototypeWithCycleCheck(exec->vm(), jsValue.isObject() ? jsValue : jsNull());
jsObject->setPrototypeWithCycleCheck(exec, jsValue.isObject() ? jsValue : jsNull());
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
......@@ -528,8 +528,6 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
if (!jsThisObject)
jsThisObject = exec->globalThisValue();
jsThisObject = jsThisObject->methodTable()->toThisObject(jsThisObject, exec);
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; i++)
argList.append(toJS(exec, arguments[i]));
......
2013-05-06 Mark Lam <mark.lam@apple.com>
Fix broken 32-bit build + some clean up in JITStubs.cpp.
https://bugs.webkit.org/show_bug.cgi?id=115684.
Reviewed by Geoffrey Garen.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JITStubs.cpp:
- removed unneeded stubs for CPU(X86_64) && USE(JSVALUE32_64).
- added some line breaks to more clearly delineate between
ports/configurations of stub code.
2013-05-05 Geoffrey Garen <ggaren@apple.com>
Rolled back in r149527 with crash fixed.
Reviewed by Oliver Hunt.
Rationalized 'this' value conversion
https://bugs.webkit.org/show_bug.cgi?id=115542
This fixes a bunch of Sputnik tests, and some bad pointer access.
The new model is that the callee always performs 'this' value conversion.
My ultimate goal is to break up resolve_with_this into single-result
opcodes. This step avoids having to add a special form of convert_this
that distinguishes callers vs callees.
Only the callee knows whether it uses 'this' and/or whether 'this'
conversion should use StrictMode, so it's most natural to perform
convert_this in the callee.
* API/JSCallbackFunction.cpp:
(JSC::JSCallbackFunction::call): Perform 'this' value conversion for
our callee, since it may observe 'this'.
* API/JSCallbackObjectFunctions.h:
(JSC::::call): Ditto.
* API/JSContextRef.cpp:
(JSGlobalContextCreateInGroup): Use a proxy 'this' object in global scope
even when we're not in the browser. This eliminates some odd cases where
API clients used to be able to get a direct reference to an environment
record. Now, any reference to an environment record unambiguously means
that the VM resolved that record in the scope chain.
(JSContextGetGlobalObject): Removed an incorrect comment. Now that JSC
participates in the proxy 'this' object scheme, the behavior is not
WebCore-only.
* API/JSObjectRef.cpp:
(JSObjectSetPrototype):
(JSObjectCallAsFunction): Don't perform 'this' value conversion in the
caller; the callee will do it if needed.
* JavaScriptCore.order: Order!
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
* JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
What are the chances that this will work?
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock): Renamed convert_this to to_this, to match our
other conversion opcodes.
* bytecode/CodeOrigin.h:
(CodeOrigin):
(InlineCallFrame):
(JSC::CodeOrigin::codeOriginOwner): Use the more precise type for our
executable, so compilation can discover where we're in strict mode.
* bytecode/Opcode.h:
(JSC::padOpcodeName): Updated for rename.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator): Always emit to_this when
'this' is in use -- strict mode still needs to convert environment
records to 'undefined'.
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode): Updated for renames.
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode): Tightened up this code to consider
strict mode (a new requirement) and to consider the global object (which
was always a requirement).
* dfg/DFGGraph.h:
(JSC::DFG::Graph::globalThisObjectFor):
(JSC::DFG::Graph::executableFor):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile): Ditto.
* interpreter/Interpreter.cpp:
(JSC::eval):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
* interpreter/Interpreter.h: Don't ASSERT about 'this' -- it's our job
to fix it up if needed.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
(JIT):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emitSlow_op_to_this):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emitSlow_op_to_this):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h: Removed special-case code for various kinds of
conversions. The baseline fast path is now final objects only. It hurt
my brain to think through how to keep the other fast paths working, and
our benchmarks do not object.
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
(LLInt):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm: Updated for renames. Removed some
special case code, as in the JIT above.
* profiler/ProfileGenerator.cpp:
(JSC::ProfileGenerator::addParentForConsoleStart):
* runtime/CallData.cpp:
(JSC::call):
* runtime/ClassInfo.h:
(MethodTable):
* runtime/Completion.cpp:
(JSC::evaluate):
* runtime/DatePrototype.cpp:
(JSC::dateProtoFuncToJSON): The callee performs 'this' conversion, not
the caller.
* runtime/GetterSetter.cpp:
(JSC::callGetter):
(JSC::callSetter):
* runtime/GetterSetter.h: Added helper functions for invoking getters
and setters from C++ code, since this was duplicated in a bunch of
places.
* runtime/JSActivation.cpp:
(JSC::JSActivation::toThis):
* runtime/JSActivation.h:
(JSActivation):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::toThisSlowCase):
(JSC::JSValue::putToPrimitive):
* runtime/JSCJSValue.h:
(JSValue):
* runtime/JSCJSValueInlines.h:
(JSC::JSValue::toThis):
* runtime/JSCell.cpp:
(JSC::JSCell::toThis):
* runtime/JSCell.h:
(JSCell):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::toThis):
* runtime/JSGlobalObject.h:
(JSGlobalObject): Filled out runtime support for converting 'this'
values as needed, according to the appropriate strictness, using
helper functions where getter/setter code was duplicated.
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncProtoGetter):
(JSC::globalFuncProtoSetter): Perform 'this' value conversion, since we
observe 'this'.
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::toThis):
* runtime/JSNameScope.h:
(JSNameScope): Same as JSActivation.
* runtime/JSObject.cpp:
(JSC::JSObject::put):
(JSC::JSObject::setPrototypeWithCycleCheck): Bug fix. Don't peform
'this' value conversion in this helper function. The __proto__
setter does this for us, since it's the function that logically observes
'this' -- and we can ASSERT so. Also, the previous code used
"globalExec()->thisValue()", which is a read past the beginning of a
buffer! I don't think this ever worked on purpose.
(JSC::JSObject::toThis):
(JSC::JSObject::fillGetterPropertySlot):
* runtime/JSObject.h:
(JSC::JSObject::inlineGetOwnPropertySlot):
* runtime/JSScope.cpp:
(JSC::JSScope::resolveWithThis):
* runtime/JSString.cpp:
(JSC::JSString::toThis):
* runtime/JSString.h:
(JSString):
* runtime/PropertySlot.cpp:
(JSC::PropertySlot::functionGetter):
* runtime/PropertySlot.h:
(JSC):
(JSC::PropertySlot::setGetterSlot):
(JSC::PropertySlot::setCacheableGetterSlot):
* runtime/SparseArrayValueMap.cpp:
(JSC::SparseArrayEntry::get):
(JSC::SparseArrayEntry::put):
* runtime/StrictEvalActivation.cpp:
(JSC::StrictEvalActivation::toThis):
* runtime/StrictEvalActivation.h:
(StrictEvalActivation): Ditto.
2013-05-03 Filip Pizlo <fpizlo@apple.com>
fourthTier: DFG::ByteCodeParser doesn't need ExecState*
......
......@@ -337,7 +337,6 @@ _JSValueToObject
__ZN3JSC12APIEntryShimC1EPNS_9ExecStateEb
__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE
_JSContextGetGlobalObject
__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
_JSStringCreateWithUTF8CString
_JSObjectGetProperty
__ZNK14OpaqueJSString10identifierEPN3JSC12VME
......@@ -812,9 +811,7 @@ __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE17staticValueGetterEPN
__ZN3WTF9HashTableISt4pairINS_6RefPtrINS_10StringImplEEEjES1_IS5_PN3JSC7JSValueEENS_18PairFirstExtractorIS9_EENS6_24StructureTransitionTable4HashENS_14PairHashTraitsINSC_10HashTraitsENS_10HashTraitsIS8_EEEESF_E6rehashEi
_JSValueMakeString
__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
__ZN3JSC3JIT20emit_op_convert_thisEPNS_11InstructionE
__ZN3JSC23MacroAssemblerX86Common11branchTest8ENS0_15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E
__ZN3JSC3JIT24emitSlow_op_convert_thisEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC8JSObject13visitChildrenERNS_9MarkStackE
__ZN3JSC14JSGlobalObject13visitChildrenERNS_9MarkStackE
__ZN3JSC9MarkStack14MarkStackArrayIPNS_6JSCellEE6appendERKS3_
......@@ -989,7 +986,6 @@ __ZThn16_N3JSC8EvalNodeD0Ev
__ZN3JSC8EvalNodeD0Ev
__ZN3WTF7HashMapINS_6RefPtrINS_10StringImplEEEN3JSC12WriteBarrierINS4_14EvalExecutableEEENS_10StringHashENS_10HashTraitsIS3_EENS9_IS7_EEE3setEPS2_RKS7_
__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC12WriteBarrierINS5_14EvalExecutableEEEENS_18PairFirstExtractorIS9_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSE_IS8_EEEESF_E6expandEv
__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
__ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeE
_cti_op_resolve
_JSValueMakeBoolean
......@@ -1436,7 +1432,6 @@ __ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_
__ZN3JSCL23createPrototypePropertyERNS_12VMEPNS_14JSGlobalObjectEPNS_10JSFunctionE
__ZNK3JSC8NullNode6isNullEv
__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE
_cti_op_convert_this
_cti_vm_lazyLinkConstruct
__ZN3JSC18FunctionExecutable27compileForConstructInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE
__ZN3JSC3JIT18emit_op_get_calleeEPNS_11InstructionE
......@@ -1558,7 +1553,6 @@ __ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
__ZN3JSC17BytecodeGenerator20emitGetArgumentByValEPNS_10RegisterIDES2_S2_
__ZN3JSC3JIT27emit_op_get_argument_by_valEPNS_11InstructionE
__ZN3JSC3JIT31emitSlow_op_get_argument_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateE
__ZN3JSC7JSArray9setLengthEj
__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
......@@ -2022,7 +2016,6 @@ __ZNK3JSC14ExpressionNode17isDotAccessorNodeEv
__ZN3JSC9ExecState22stringConstructorTableEPS0_
__ZN3JSCL26stringFromCharCodeSlowCaseEPNS_9ExecStateE
__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateE
__ZNK3JSC12JSActivation12toThisObjectEPNS_9ExecStateE
__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
__ZN3JSC9ExecState11stringTableEPS0_
__ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
......@@ -2269,8 +2262,6 @@ __ZN3JSC12JSActivation18getArgumentsGetterEv
__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
__ZN3JSCL20arrayProtoFuncReduceEPNS_9ExecStateE
__ZN3JSCL25arrayProtoFuncReduceRightEPNS_9ExecStateE
__ZN3JSC3JIT27emit_op_convert_this_strictEPNS_11InstructionE
__ZN3JSC3JIT31emitSlow_op_convert_this_strictEPNS_11InstructionERPNS_13SlowCaseEntryE
__ZN3JSC9Arguments33createStrictModeCalleeIfNecessaryEPNS_9ExecStateE
__ZN3JSC23createTypeErrorFunctionEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j
......@@ -2339,7 +2330,6 @@ __ZN3JSCL25objectConstructorIsSealedEPNS_9ExecStateE
__ZN3JSCL25objectConstructorIsFrozenEPNS_9ExecStateE
__ZN3JSCL29objectConstructorIsExtensibleEPNS_9ExecStateE
__ZN3JSC4Yarr25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt
__ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE
__ZN3JSCL23stringProtoFuncTrimLeftEPNS_9ExecStateE
__ZN3JSCL24stringProtoFuncTrimRightEPNS_9ExecStateE
__ZN3WTF6VectorIcLm0EE14expandCapacityEm
......
......@@ -716,9 +716,9 @@ void CodeBlock::dumpBytecode(PrintStream& out, ExecState* exec, const Instructio
out.printf("[%4d] create_this %s, %s, %u", location, registerName(r0).data(), registerName(r1).data(), inferredInlineCapacity);
break;
}
case op_convert_this: {
case op_to_this: {
int r0 = (++it)->u.operand;
out.printf("[%4d] convert_this\t %s", location, registerName(r0).data());
out.printf("[%4d] to_this\t %s", location, registerName(r0).data());
++it; // Skip value profile.
break;
}
......@@ -1774,7 +1774,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin
instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
// fallthrough
}
case op_convert_this:
case op_to_this:
case op_get_by_id:
case op_call_put_result:
case op_get_callee: {
......
......@@ -39,7 +39,7 @@ namespace JSC {
struct InlineCallFrame;
class ExecState;
class ExecutableBase;
class ScriptExecutable;
class JSFunction;
struct CodeOrigin {
......@@ -82,7 +82,7 @@ struct CodeOrigin {
// If the code origin corresponds to inlined code, gives you the heap object that
// would have owned the code if it had not been inlined. Otherwise returns 0.
ExecutableBase* codeOriginOwner() const;
ScriptExecutable* codeOriginOwner() const;
unsigned stackOffset() const;
......@@ -100,7 +100,7 @@ struct CodeOrigin {
struct InlineCallFrame {
Vector<ValueRecovery> arguments;
WriteBarrier<ExecutableBase> executable;
WriteBarrier<ScriptExecutable> executable;
WriteBarrier<JSFunction> callee; // This may be null, indicating that this is a closure call and that the JSFunction and JSScope are already on the stack.
CodeOrigin caller;
BitVector capturedVars; // Indexed by the machine call frame's variable numbering.
......@@ -149,7 +149,7 @@ inline unsigned getCallReturnOffsetForCodeOrigin(CodeOriginAtCallReturnOffset* d
return data->callReturnOffset;
}
inline ExecutableBase* CodeOrigin::codeOriginOwner() const
inline ScriptExecutable* CodeOrigin::codeOriginOwner() const
{
if (!inlineCallFrame)
return 0;
......
......@@ -46,7 +46,7 @@ namespace JSC {
macro(op_create_arguments, 2) \
macro(op_create_this, 4) \
macro(op_get_callee, 3) \
macro(op_convert_this, 3) \
macro(op_to_this, 3) \
\
macro(op_new_object, 4) \
macro(op_new_array, 5) \
......
......@@ -395,8 +395,8 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope* scope, FunctionBodyNode* f
if (isConstructor()) {
emitCreateThis(&m_thisRegister);
} else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) {
UnlinkedValueProfile profile = emitProfiledOpcode(op_convert_this);
} else if (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks) {
UnlinkedValueProfile profile = emitProfiledOpcode(op_to_this);
instructions().append(kill(&m_thisRegister));
instructions().append(profile);
}
......
......@@ -1139,7 +1139,7 @@ bool AbstractState::executeEffects(unsigned indexInBlock, Node* node)
m_haveStructures = true;
break;
case ConvertThis: {
case ToThis: {
AbstractValue& source = forNode(node->child1());
AbstractValue& destination = forNode(node);
......
......@@ -2025,9 +2025,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
set(i, constantUndefined(), SetOnEntry);
NEXT_OPCODE(op_enter);
case op_convert_this: {
case op_to_this: {
Node* op1 = getThis();
if (op1->op() != ConvertThis) {
if (op1->op() != ToThis) {
CodeBlockLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
ValueProfile* profile =
m_inlineStackTop->m_profiledBlock->valueProfileForBytecodeOffset(m_currentProfilingIndex);
......@@ -2041,7 +2041,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
|| !profile->m_singletonValue
|| !profile->m_singletonValue.isCell()
|| profile->m_singletonValue.asCell()->classInfo() != &Structure::s_info)
setThis(addToGraph(ConvertThis, op1));
setThis(addToGraph(ToThis, op1));
else {
addToGraph(
CheckStructure,
......@@ -2049,7 +2049,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
op1);
}
}
NEXT_OPCODE(op_convert_this);
NEXT_OPCODE(op_to_this);
}
case op_create_this: {
......
......@@ -86,7 +86,7 @@ inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instructi
{
switch (opcodeID) {
case op_enter:
case op_convert_this: