Changeset 129281 in webkit
- Timestamp:
- Sep 21, 2012 5:43:03 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r129279 r129281 1 2012-09-21 Gavin Barraclough <barraclough@apple.com> 2 3 instanceof should not get the prototype for non-default HasInstance 4 https://bugs.webkit.org/show_bug.cgi?id=68656 5 6 Reviewed by Oliver Hunt. 7 8 * fast/js/function-bind-expected.txt: 9 - check in passing result. 10 1 11 2012-09-21 Benjamin Poulain <bpoulain@apple.com> 2 12 -
trunk/LayoutTests/fast/js/function-bind-expected.txt
r108729 r129281 27 27 [native code] 28 28 }' is not a constructor (evaluating 'new abcAt(1)'). 29 FAIL boundFunctionPrototypeAccessed should be false. Was true. 29 PASS boundFunctionPrototypeAccessed is false 30 30 PASS Function.bind.length is 1 31 31 PASS successfullyParsed is true -
trunk/Source/JavaScriptCore/API/JSCallbackObject.h
r128851 r129281 187 187 static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned); 188 188 189 static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);189 static bool customHasInstance(JSObject*, ExecState*, JSValue); 190 190 191 191 static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); -
trunk/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
r128400 r129281 390 390 391 391 template <class Parent> 392 bool JSCallbackObject<Parent>:: hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)392 bool JSCallbackObject<Parent>::customHasInstance(JSObject* object, ExecState* exec, JSValue value) 393 393 { 394 394 JSCallbackObject* thisObject = jsCast<JSCallbackObject*>(object); -
trunk/Source/JavaScriptCore/API/JSValueRef.cpp
r128851 r129281 176 176 if (!jsConstructor->structure()->typeInfo().implementsHasInstance()) 177 177 return false; 178 bool result = jsConstructor-> methodTable()->hasInstance(jsConstructor, exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown178 bool result = jsConstructor->hasInstance(exec, jsValue); // false if an exception is thrown 179 179 if (exec->hadException()) { 180 180 if (exception) -
trunk/Source/JavaScriptCore/ChangeLog
r129274 r129281 1 2012-09-21 Gavin Barraclough <barraclough@apple.com> 2 3 instanceof should not get the prototype for non-default HasInstance 4 https://bugs.webkit.org/show_bug.cgi?id=68656 5 6 Reviewed by Oliver Hunt. 7 8 Instanceof is currently implemented as a sequance of three opcodes: 9 check_has_instance 10 get_by_id(prototype) 11 op_instanceof 12 There are three interesting types of base value that instanceof can be applied to: 13 (A) Objects supporting default instanceof behaviour (functions, other than those created with bind) 14 (B) Objects overriding the default instancecof behaviour with a custom one (API objects, bound functions) 15 (C) Values that do not respond to the [[HasInstance]] trap. 16 Currently check_has_instance handles case (C), leaving the op_instanceof opcode to handle (A) & (B). There are 17 two problems with this apporach. Firstly, this is suboptimal for case (A), since we have to check for 18 hasInstance support twice (once in check_has_instance, then for default behaviour in op_instanceof). Secondly, 19 this means that in cases (B) we also perform the get_by_id, which is both suboptimal and an observable spec 20 violation. 21 22 The fix here is to move handing of non-default instanceof (cases (B)) to the check_has_instance op, leaving 23 op_instanceof to handle only cases (A). 24 25 * API/JSCallbackObject.h: 26 (JSCallbackObject): 27 * API/JSCallbackObjectFunctions.h: 28 (JSC::::customHasInstance): 29 * API/JSValueRef.cpp: 30 (JSValueIsInstanceOfConstructor): 31 - renamed hasInstance to customHasInstance 32 * bytecode/CodeBlock.cpp: 33 (JSC::CodeBlock::dump): 34 - added additional parameters to check_has_instance opcode 35 * bytecode/Opcode.h: 36 (JSC): 37 (JSC::padOpcodeName): 38 - added additional parameters to check_has_instance opcode 39 * bytecompiler/BytecodeGenerator.cpp: 40 (JSC::BytecodeGenerator::emitCheckHasInstance): 41 - added additional parameters to check_has_instance opcode 42 * bytecompiler/BytecodeGenerator.h: 43 (BytecodeGenerator): 44 - added additional parameters to check_has_instance opcode 45 * bytecompiler/NodesCodegen.cpp: 46 (JSC::InstanceOfNode::emitBytecode): 47 - added additional parameters to check_has_instance opcode 48 * dfg/DFGByteCodeParser.cpp: 49 (JSC::DFG::ByteCodeParser::parseBlock): 50 - added additional parameters to check_has_instance opcode 51 * interpreter/Interpreter.cpp: 52 (JSC::isInvalidParamForIn): 53 (JSC::Interpreter::privateExecute): 54 - Add handling for non-default instanceof to op_check_has_instance 55 * jit/JITInlineMethods.h: 56 (JSC::JIT::emitArrayProfilingSiteForBytecodeIndex): 57 - Fixed no-LLInt no_DFG build 58 * jit/JITOpcodes.cpp: 59 (JSC::JIT::emit_op_check_has_instance): 60 (JSC::JIT::emitSlow_op_check_has_instance): 61 - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. 62 (JSC::JIT::emit_op_instanceof): 63 (JSC::JIT::emitSlow_op_instanceof): 64 - no need to check for ImplementsDefaultHasInstance. 65 * jit/JITOpcodes32_64.cpp: 66 (JSC::JIT::emit_op_check_has_instance): 67 (JSC::JIT::emitSlow_op_check_has_instance): 68 - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. 69 (JSC::JIT::emit_op_instanceof): 70 (JSC::JIT::emitSlow_op_instanceof): 71 - no need to check for ImplementsDefaultHasInstance. 72 * jit/JITStubs.cpp: 73 (JSC::DEFINE_STUB_FUNCTION): 74 * jit/JITStubs.h: 75 - Add handling for non-default instanceof to op_check_has_instance 76 * llint/LLIntSlowPaths.cpp: 77 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 78 * llint/LowLevelInterpreter32_64.asm: 79 * llint/LowLevelInterpreter64.asm: 80 - move check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. 81 * runtime/ClassInfo.h: 82 (MethodTable): 83 (JSC): 84 - renamed hasInstance to customHasInstance 85 * runtime/CommonSlowPaths.h: 86 (CommonSlowPaths): 87 - removed opInstanceOfSlow (this was whittled down to one function call!) 88 * runtime/JSBoundFunction.cpp: 89 (JSC::JSBoundFunction::customHasInstance): 90 * runtime/JSBoundFunction.h: 91 (JSBoundFunction): 92 - renamed hasInstance to customHasInstance, reimplemented. 93 * runtime/JSCell.cpp: 94 (JSC::JSCell::customHasInstance): 95 * runtime/JSCell.h: 96 (JSCell): 97 * runtime/JSObject.cpp: 98 (JSC::JSObject::hasInstance): 99 (JSC): 100 (JSC::JSObject::defaultHasInstance): 101 * runtime/JSObject.h: 102 (JSObject): 103 1 104 2012-09-21 Filip Pizlo <fpizlo@apple.com> 2 105 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r128534 r129281 874 874 } 875 875 case op_check_has_instance: { 876 int base = (++it)->u.operand; 877 dataLog("[%4d] check_has_instance\t\t %s", location, registerName(exec, base).data()); 876 int r0 = (++it)->u.operand; 877 int r1 = (++it)->u.operand; 878 int r2 = (++it)->u.operand; 879 int offset = (++it)->u.operand; 880 dataLog("[%4d] check_has_instance\t\t %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), offset, location + offset); 878 881 dumpBytecodeCommentAndNewLine(location); 879 882 break; -
trunk/Source/JavaScriptCore/bytecode/Opcode.h
r128534 r129281 85 85 macro(op_bitor, 5) \ 86 86 \ 87 macro(op_check_has_instance, 2) \87 macro(op_check_has_instance, 5) \ 88 88 macro(op_instanceof, 5) \ 89 89 macro(op_typeof, 3) \ -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r128832 r129281 1458 1458 } 1459 1459 1460 void BytecodeGenerator::emitCheckHasInstance(RegisterID* base) 1461 { 1460 void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target) 1461 { 1462 size_t begin = instructions().size(); 1462 1463 emitOpcode(op_check_has_instance); 1464 instructions().append(dst->index()); 1465 instructions().append(value->index()); 1463 1466 instructions().append(base->index()); 1467 instructions().append(target->bind(begin, instructions().size())); 1464 1468 } 1465 1469 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r128534 r129281 456 456 RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst); 457 457 458 void emitCheckHasInstance(RegisterID* base);458 void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target); 459 459 RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype); 460 460 RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); } -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r129156 r129281 1089 1089 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 1090 1090 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2); 1091 RefPtr<RegisterID> prototype = generator.newTemporary(); 1092 RefPtr<RegisterID> dstReg = generator.finalDestination(dst, src1.get()); 1093 RefPtr<Label> target = generator.newLabel(); 1091 1094 1092 1095 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1093 generator.emitCheckHasInstance( src2.get());1096 generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get()); 1094 1097 1095 1098 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1096 RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);1099 generator.emitGetById(prototype.get(), src2.get(), generator.globalData()->propertyNames->prototype); 1097 1100 1098 1101 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1099 return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype); 1102 RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), src2.get(), prototype.get()); 1103 generator.emitLabel(target.get()); 1104 return result; 1100 1105 } 1101 1106 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r129156 r129281 2050 2050 2051 2051 case op_check_has_instance: 2052 addToGraph(CheckHasInstance, get(currentInstruction[ 1].u.operand));2052 addToGraph(CheckHasInstance, get(currentInstruction[3].u.operand)); 2053 2053 NEXT_OPCODE(op_check_has_instance); 2054 2054 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r129156 r129281 130 130 return false; 131 131 exceptionData = createInvalidParamError(callFrame, "in" , value); 132 return true;133 }134 135 static NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, JSValue value, JSValue& exceptionData)136 {137 if (value.isObject() && asObject(value)->structure()->typeInfo().implementsHasInstance())138 return false;139 exceptionData = createInvalidParamError(callFrame, "instanceof" , value);140 132 return true; 141 133 } … … 2402 2394 an valid parameter for instanceof. 2403 2395 */ 2404 int base = vPC[1].u.operand; 2396 int dst = vPC[1].u.operand; 2397 int value = vPC[2].u.operand; 2398 int base = vPC[3].u.operand; 2399 int target = vPC[4].u.operand; 2400 2405 2401 JSValue baseVal = callFrame->r(base).jsValue(); 2406 2402 2407 if (isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue)) 2408 goto vm_throw; 2409 2410 vPC += OPCODE_LENGTH(op_check_has_instance); 2411 NEXT_INSTRUCTION(); 2403 if (baseVal.isObject()) { 2404 TypeInfo info = asObject(baseVal)->structure()->typeInfo(); 2405 if (info.implementsDefaultHasInstance()) { 2406 vPC += OPCODE_LENGTH(op_check_has_instance); 2407 NEXT_INSTRUCTION(); 2408 } 2409 if (info.implementsHasInstance()) { 2410 JSValue baseVal = callFrame->r(base).jsValue(); 2411 bool result = asObject(baseVal)->methodTable()->customHasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue()); 2412 CHECK_FOR_EXCEPTION(); 2413 callFrame->uncheckedR(dst) = jsBoolean(result); 2414 2415 vPC += target; 2416 NEXT_INSTRUCTION(); 2417 } 2418 } 2419 2420 exceptionValue = createInvalidParamError(callFrame, "instanceof" , baseVal); 2421 goto vm_throw; 2412 2422 } 2413 2423 DEFINE_OPCODE(op_instanceof) { … … 2426 2436 int dst = vPC[1].u.operand; 2427 2437 int value = vPC[2].u.operand; 2428 int base = vPC[3].u.operand;2429 2438 int baseProto = vPC[4].u.operand; 2430 2439 2431 JSValue baseVal = callFrame->r(base).jsValue(); 2432 2433 ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue)); 2434 2435 bool result = asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue()); 2440 ASSERT(callFrame->r(vPC[3].u.operand).jsValue().isObject() && asObject(callFrame->r(vPC[3].u.operand).jsValue())->structure()->typeInfo().implementsDefaultHasInstance()); 2441 2442 bool result = JSObject::defaultHasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue()); 2436 2443 CHECK_FOR_EXCEPTION(); 2437 2444 callFrame->uncheckedR(dst) = jsBoolean(result); -
trunk/Source/JavaScriptCore/jit/JITInlineMethods.h
r129045 r129281 553 553 emitArrayProfilingSite(structureAndIndexingType, scratch, m_codeBlock->getOrAddArrayProfile(bytecodeIndex)); 554 554 #else 555 UNUSED_PARAM(bytecodeIndex); 555 556 emitArrayProfilingSite(structureAndIndexingType, scratch, 0); 556 557 #endif -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r128802 r129281 408 408 void JIT::emit_op_check_has_instance(Instruction* currentInstruction) 409 409 { 410 unsigned baseVal = currentInstruction[ 1].u.operand;410 unsigned baseVal = currentInstruction[3].u.operand; 411 411 412 412 emitGetVirtualRegister(baseVal, regT0); … … 417 417 // Check that baseVal 'ImplementsHasInstance'. 418 418 loadPtr(Address(regT0, JSCell::structureOffset()), regT0); 419 addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(Implements HasInstance)));419 addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance))); 420 420 } 421 421 … … 424 424 unsigned dst = currentInstruction[1].u.operand; 425 425 unsigned value = currentInstruction[2].u.operand; 426 unsigned baseVal = currentInstruction[3].u.operand;427 426 unsigned proto = currentInstruction[4].u.operand; 428 427 … … 430 429 // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. 431 430 emitGetVirtualRegister(value, regT2); 432 emitGetVirtualRegister(baseVal, regT0);433 431 emitGetVirtualRegister(proto, regT1); 434 432 … … 441 439 addSlowCase(emitJumpIfNotObject(regT3)); 442 440 443 // Fixme: this check is only needed because the JSC API allows HasInstance to be overridden; we should deprecate this.444 // Check that baseVal 'ImplementsDefaultHasInstance'.445 loadPtr(Address(regT0, JSCell::structureOffset()), regT0);446 addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));447 448 441 // Optimistically load the result true, and start looping. 449 442 // Initially, regT1 still contains proto and regT2 still contains value. … … 1453 1446 void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1454 1447 { 1455 unsigned baseVal = currentInstruction[1].u.operand; 1448 unsigned dst = currentInstruction[1].u.operand; 1449 unsigned value = currentInstruction[2].u.operand; 1450 unsigned baseVal = currentInstruction[3].u.operand; 1456 1451 1457 1452 linkSlowCaseIfNotJSCell(iter, baseVal); 1458 1453 linkSlowCase(iter); 1459 1454 JITStubCall stubCall(this, cti_op_check_has_instance); 1455 stubCall.addArgument(value, regT2); 1460 1456 stubCall.addArgument(baseVal, regT2); 1461 stubCall.call(); 1457 stubCall.call(dst); 1458 1459 emitJumpSlowToHot(jump(), currentInstruction[4].u.operand); 1462 1460 } 1463 1461 … … 1471 1469 linkSlowCaseIfNotJSCell(iter, value); 1472 1470 linkSlowCaseIfNotJSCell(iter, proto); 1473 linkSlowCase(iter);1474 1471 linkSlowCase(iter); 1475 1472 JITStubCall stubCall(this, cti_op_instanceof); -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r128122 r129281 544 544 void JIT::emit_op_check_has_instance(Instruction* currentInstruction) 545 545 { 546 unsigned baseVal = currentInstruction[ 1].u.operand;546 unsigned baseVal = currentInstruction[3].u.operand; 547 547 548 548 emitLoadPayload(baseVal, regT0); … … 553 553 // Check that baseVal 'ImplementsHasInstance'. 554 554 loadPtr(Address(regT0, JSCell::structureOffset()), regT0); 555 addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(Implements HasInstance)));555 addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance))); 556 556 } 557 557 … … 560 560 unsigned dst = currentInstruction[1].u.operand; 561 561 unsigned value = currentInstruction[2].u.operand; 562 unsigned baseVal = currentInstruction[3].u.operand;563 562 unsigned proto = currentInstruction[4].u.operand; 564 563 … … 566 565 // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result. 567 566 emitLoadPayload(value, regT2); 568 emitLoadPayload(baseVal, regT0);569 567 emitLoadPayload(proto, regT1); 570 568 … … 576 574 loadPtr(Address(regT1, JSCell::structureOffset()), regT3); 577 575 addSlowCase(emitJumpIfNotObject(regT3)); 578 579 // Fixme: this check is only needed because the JSC API allows HasInstance to be overridden; we should deprecate this.580 // Check that baseVal 'ImplementsDefaultHasInstance'.581 loadPtr(Address(regT0, JSCell::structureOffset()), regT0);582 addSlowCase(branchTest8(Zero, Address(regT0, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance)));583 576 584 577 // Optimistically load the result true, and start looping. … … 605 598 void JIT::emitSlow_op_check_has_instance(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 606 599 { 607 unsigned baseVal = currentInstruction[1].u.operand; 600 unsigned dst = currentInstruction[1].u.operand; 601 unsigned value = currentInstruction[2].u.operand; 602 unsigned baseVal = currentInstruction[3].u.operand; 608 603 609 604 linkSlowCaseIfNotJSCell(iter, baseVal); … … 611 606 612 607 JITStubCall stubCall(this, cti_op_check_has_instance); 608 stubCall.addArgument(value); 613 609 stubCall.addArgument(baseVal); 614 stubCall.call(); 610 stubCall.call(dst); 611 612 emitJumpSlowToHot(jump(), currentInstruction[4].u.operand); 615 613 } 616 614 … … 624 622 linkSlowCaseIfNotJSCell(iter, value); 625 623 linkSlowCaseIfNotJSCell(iter, proto); 626 linkSlowCase(iter);627 624 linkSlowCase(iter); 628 625 -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r128832 r129281 1938 1938 } 1939 1939 1940 DEFINE_STUB_FUNCTION(void, op_check_has_instance) 1941 { 1942 STUB_INIT_STACK_FRAME(stackFrame); 1943 1944 CallFrame* callFrame = stackFrame.callFrame; 1945 JSValue baseVal = stackFrame.args[0].jsValue(); 1946 1947 // ECMA-262 15.3.5.3: 1948 // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function). 1949 #ifndef NDEBUG 1950 TypeInfo typeInfo(UnspecifiedType); 1951 ASSERT(!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()); 1952 #endif 1940 DEFINE_STUB_FUNCTION(EncodedJSValue, op_check_has_instance) 1941 { 1942 STUB_INIT_STACK_FRAME(stackFrame); 1943 1944 CallFrame* callFrame = stackFrame.callFrame; 1945 JSValue value = stackFrame.args[0].jsValue(); 1946 JSValue baseVal = stackFrame.args[1].jsValue(); 1947 1948 if (baseVal.isObject()) { 1949 JSObject* baseObject = asObject(baseVal); 1950 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance()); 1951 if (baseObject->structure()->typeInfo().implementsHasInstance()) { 1952 bool result = baseObject->methodTable()->customHasInstance(baseObject, callFrame, value); 1953 CHECK_FOR_EXCEPTION_AT_END(); 1954 return JSValue::encode(jsBoolean(result)); 1955 } 1956 } 1957 1953 1958 stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal); 1954 1959 VM_THROW_EXCEPTION_AT_END(); 1960 return JSValue::encode(JSValue()); 1955 1961 } 1956 1962 … … 2083 2089 CallFrame* callFrame = stackFrame.callFrame; 2084 2090 JSValue value = stackFrame.args[0].jsValue(); 2085 JSValue baseVal = stackFrame.args[1].jsValue();2086 2091 JSValue proto = stackFrame.args[2].jsValue(); 2087 2092 2088 bool result = CommonSlowPaths::opInstanceOfSlow(callFrame, value, baseVal, proto); 2093 ASSERT(stackFrame.args[1].jsValue().isObject() && asObject(stackFrame.args[1].jsValue())->structure()->typeInfo().implementsDefaultHasInstance()); 2094 ASSERT(!value.isObject() || !proto.isObject()); 2095 2096 bool result = JSObject::defaultHasInstance(callFrame, value, proto); 2089 2097 CHECK_FOR_EXCEPTION_AT_END(); 2090 2098 return JSValue::encode(jsBoolean(result)); -
trunk/Source/JavaScriptCore/jit/JITStubs.h
r127394 r129281 351 351 EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION) WTF_INTERNAL; 352 352 EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL; 353 EncodedJSValue JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL; 353 354 EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION) WTF_INTERNAL; 354 355 EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION) WTF_INTERNAL; … … 432 433 int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; 433 434 int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION) WTF_INTERNAL; 434 void JIT_STUB cti_op_check_has_instance(STUB_ARGS_DECLARATION) WTF_INTERNAL;435 435 void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION) WTF_INTERNAL; 436 436 void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r128832 r129281 719 719 { 720 720 LLINT_BEGIN(); 721 JSValue baseVal = LLINT_OP_C(1).jsValue(); 722 #ifndef NDEBUG 723 TypeInfo typeInfo(UnspecifiedType); 724 ASSERT(!baseVal.isObject() 725 || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()); 726 #endif 721 722 JSValue value = LLINT_OP_C(2).jsValue(); 723 JSValue baseVal = LLINT_OP_C(3).jsValue(); 724 if (baseVal.isObject()) { 725 JSObject* baseObject = asObject(baseVal); 726 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance()); 727 if (baseObject->structure()->typeInfo().implementsHasInstance()) { 728 pc += pc[4].u.operand; 729 LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value))); 730 } 731 } 727 732 LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal)); 728 733 } … … 731 736 { 732 737 LLINT_BEGIN(); 733 LLINT_RETURN(jsBoolean(CommonSlowPaths::opInstanceOfSlow(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue()))); 738 JSValue value = LLINT_OP_C(2).jsValue(); 739 JSValue proto = LLINT_OP_C(4).jsValue(); 740 ASSERT(LLINT_OP_C(3).jsValue().isObject() && asObject(LLINT_OP_C(3).jsValue())->structure()->typeInfo().implementsDefaultHasInstance()); 741 ASSERT(!value.isObject() || !proto.isObject()); 742 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto))); 734 743 } 735 744 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r129045 r129281 834 834 _llint_op_check_has_instance: 835 835 traceExecution() 836 loadi 4[PC], t1836 loadi 12[PC], t1 837 837 loadConstantOrVariablePayload(t1, CellTag, t0, .opCheckHasInstanceSlow) 838 838 loadp JSCell::m_structure[t0], t0 839 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], Implements HasInstance, .opCheckHasInstanceSlow840 dispatch( 2)839 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow 840 dispatch(5) 841 841 842 842 .opCheckHasInstanceSlow: 843 843 callSlowPath(_llint_slow_path_check_has_instance) 844 dispatch( 2)844 dispatch(0) 845 845 846 846 847 847 _llint_op_instanceof: 848 848 traceExecution() 849 # Check that baseVal implements the default HasInstance behavior.850 # FIXME: This should be deprecated.851 loadi 12[PC], t1852 loadConstantOrVariablePayloadUnchecked(t1, t0)853 loadp JSCell::m_structure[t0], t0854 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow855 856 849 # Actually do the work. 857 850 loadi 16[PC], t0 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r129045 r129281 692 692 _llint_op_check_has_instance: 693 693 traceExecution() 694 loadis 8[PB, PC, 8], t1694 loadis 24[PB, PC, 8], t1 695 695 loadConstantOrVariableCell(t1, t0, .opCheckHasInstanceSlow) 696 696 loadp JSCell::m_structure[t0], t0 697 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], Implements HasInstance, .opCheckHasInstanceSlow698 dispatch( 2)697 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow 698 dispatch(5) 699 699 700 700 .opCheckHasInstanceSlow: 701 701 callSlowPath(_llint_slow_path_check_has_instance) 702 dispatch( 2)702 dispatch(0) 703 703 704 704 705 705 _llint_op_instanceof: 706 706 traceExecution() 707 # Check that baseVal implements the default HasInstance behavior.708 # FIXME: This should be deprecated.709 loadis 24[PB, PC, 8], t1710 loadConstantOrVariable(t1, t0)711 loadp JSCell::m_structure[t0], t0712 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opInstanceofSlow713 714 707 # Actually do the work. 715 708 loadis 32[PB, PC, 8], t0 -
trunk/Source/JavaScriptCore/runtime/ClassInfo.h
r128400 r129281 82 82 ClassNameFunctionPtr className; 83 83 84 typedef bool (* HasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue, JSValue);85 HasInstanceFunctionPtr hasInstance;84 typedef bool (*CustomHasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue); 85 CustomHasInstanceFunctionPtr customHasInstance; 86 86 87 87 typedef void (*PutWithAttributesFunctionPtr)(JSObject*, ExecState*, PropertyName propertyName, JSValue, unsigned attributes); … … 131 131 &ClassName::getPropertyNames, \ 132 132 &ClassName::className, \ 133 &ClassName:: hasInstance, \133 &ClassName::customHasInstance, \ 134 134 &ClassName::putDirectVirtual, \ 135 135 &ClassName::defineOwnProperty, \ -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h
r126893 r129281 76 76 } 77 77 78 ALWAYS_INLINE bool opInstanceOfSlow(ExecState* exec, JSValue value, JSValue baseVal, JSValue proto)79 {80 ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()81 || !value.isObject() || !baseVal.isObject() || !proto.isObject()82 || !asObject(baseVal)->structure()->typeInfo().implementsDefaultHasInstance());83 84 85 // ECMA-262 15.3.5.3:86 // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).87 TypeInfo typeInfo(UnspecifiedType);88 if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) {89 exec->globalData().exception = createInvalidParamError(exec, "instanceof", baseVal);90 return false;91 }92 ASSERT(typeInfo.type() != UnspecifiedType);93 94 if (!typeInfo.overridesHasInstance() && !value.isObject())95 return false;96 97 return asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), exec, value, proto);98 }99 100 78 inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal) 101 79 { -
trunk/Source/JavaScriptCore/runtime/JSBoundFunction.cpp
r128400 r129281 90 90 } 91 91 92 bool JSBoundFunction:: hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue)92 bool JSBoundFunction::customHasInstance(JSObject* object, ExecState* exec, JSValue value) 93 93 { 94 JSBoundFunction* thisObject = jsCast<JSBoundFunction*>(object); 95 // FIXME: our instanceof implementation will have already (incorrectly) performed 96 // a [[Get]] of .prototype from the bound function object, which is incorrect! 97 // https://bugs.webkit.org/show_bug.cgi?id=68656 98 JSValue proto = thisObject->m_targetFunction->get(exec, exec->propertyNames().prototype); 99 return thisObject->m_targetFunction->methodTable()->hasInstance(thisObject->m_targetFunction.get(), exec, value, proto); 94 return jsCast<JSBoundFunction*>(object)->m_targetFunction->hasInstance(exec, value); 100 95 } 101 96 -
trunk/Source/JavaScriptCore/runtime/JSBoundFunction.h
r127191 r129281 40 40 static JSBoundFunction* create(ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&); 41 41 42 static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto);42 static bool customHasInstance(JSObject*, ExecState*, JSValue); 43 43 44 44 JSObject* targetFunction() { return m_targetFunction.get(); } -
trunk/Source/JavaScriptCore/runtime/JSCell.cpp
r128400 r129281 200 200 } 201 201 202 bool JSCell:: hasInstance(JSObject*, ExecState*, JSValue, JSValue)202 bool JSCell::customHasInstance(JSObject*, ExecState*, JSValue) 203 203 { 204 204 ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r128900 r129281 161 161 static NO_RETURN_DUE_TO_ASSERT void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); 162 162 static String className(const JSObject*); 163 static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty);163 JS_EXPORT_PRIVATE static bool customHasInstance(JSObject*, ExecState*, JSValue); 164 164 static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); 165 165 static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r129179 r129281 784 784 } 785 785 786 bool JSObject::hasInstance(JSObject*, ExecState* exec, JSValue value, JSValue proto) 786 bool JSObject::hasInstance(ExecState* exec, JSValue value) 787 { 788 TypeInfo info = structure()->typeInfo(); 789 if (info.implementsDefaultHasInstance()) 790 return defaultHasInstance(exec, value, get(exec, exec->propertyNames().prototype)); 791 if (info.implementsHasInstance()) 792 return methodTable()->customHasInstance(this, exec, value); 793 throwError(exec, createInvalidParamError(exec, "instanceof" , this)); 794 return false; 795 } 796 797 bool JSObject::defaultHasInstance(ExecState* exec, JSValue value, JSValue proto) 787 798 { 788 799 if (!value.isObject()) -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r129179 r129281 307 307 JS_EXPORT_PRIVATE static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); 308 308 309 JS_EXPORT_PRIVATE static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty); 309 bool hasInstance(ExecState*, JSValue); 310 static bool defaultHasInstance(ExecState*, JSValue, JSValue prototypeProperty); 310 311 311 312 JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
Note: See TracChangeset
for help on using the changeset viewer.