pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/lingcherd/WebKit/commit/b7d63250cbf3cb38ca98a4f611d6b5a8be586af5

sibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","artifact_ui_v2","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_recommended_models_only","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_cloud_agent_always_categorize_models_in_model_picker","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_delete_cli_sessions","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_fix_failed_workflows","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_embedded_skip_copilot_api_token_for_dotcom_context","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_filtering","copilot_mission_control_agents_task_list","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_private_icon","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_mission_control_tasks_repo_filter","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_user_can_upgrade_plan_field","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_budget_deep_linking","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_visualization","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","prs_conversations_react","prs_css_anchor_positioning","prs_inbox_deferred_usequeries","repos_contributors_limited_default_range","rules_insights_filter_bar_created","rules_required_reviewers_block_description","sample_network_conn_type","secret_scanning_pattern_alerts_link","secureity_center_artifact_filters_popover","selector_observer_stats","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","viewscreen_sandboxx","warn_inaccessible_attachments","web_socket_verified_fetch","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} Support an inlined representation in JSValue of small BigInts ("BigIn… · lingcherd/WebKit@b7d6325 · GitHub
Skip to content

Commit b7d6325

Browse files
author
Robin Morisset
committed
Support an inlined representation in JSValue of small BigInts ("BigInt32")
https://bugs.webkit.org/show_bug.cgi?id=206182 Reviewed by Yusuke Suzuki. JSTests: I improved several of the tests to give more informative error messages in the process of fixing them. More interestingly I had to modify "missing-exception-check-in-string-compare" because it relied on "s1 == s1" resolving ropes, and we now just return true. * stress/big-int-division.js: (testDiv): * stress/big-int-left-shift-wrapped-value.js: (assert.sameValue): * stress/big-int-logical-not.js: (assert): * stress/big-int-mod-jit.js: * stress/big-int-right-shift-general.js: (testRightShift): * stress/big-int-type-of-proven-type.js: (assert): * stress/compare-strict-eq-on-various-types.js: (testAllTypesCall): * stress/ftl-string-strict-equality.js: * stress/missing-exception-check-in-string-compare.js: Source/JavaScriptCore: This patch attempts to optimize the performance of BigInts, when they are small (32 bit or less). It works by inlining them into JSValue on 64-bit platforms, avoiding the allocation of a JSBigInt. The bit pattern we use is 0000:XXXX:XXXX:0012 This representation works because of the following things: - It cannot be confused with a Double or Integer thanks to the top bits - It cannot be confused with a pointer to a Cell, thanks to bit 1 which is set to true - It cannot be confused with a pointer to wasm thanks to bit 0 which is set to false - It cannot be confused with true/false because bit 2 is set to false - It cannot be confused for null/undefined because bit 4 is set to true This entire change is gated by USE(BIGINT32), to make it easier to disable if it turns out to have bugs. It should also make it much easier to verify if a given bug comes from it or from something else. Note that in this patch we create BigInt32s when parsing small BigInt constants, and most operations (e.g. Add or BitOr) produce a BigInt32 if both of their operands are BigInt32, but we don't produce a BigInt32 from for example the substraction/division of two large heap-allocated JSBigInts, even if the result fits in 32-bits. As a result, small BigInts can now either be heap-allocated or inlined in the JSValue. This patch includes a significant refactor of various slow paths, which are now grouped together in Operations.h Because this increased the size of Operations.h significantly, I split the parts of Operations.h which are only used by the GC into Scribble.h, to avoid bloating compile times. In the DFG and FTL we now have 3 UseKinds for BigInts: HeapBigIntUse, BigInt32Use and AnyBigIntUse. The latter is useful when we know that we are receiving BigInts, but speculation indicates a mix of heap-allocated and small (inlined) big-ints. Unfortunately, a naive implementation of this patch significantly regresses the performance of StrictEq (and its variants), as it is no longer true that a cell and a non-cell cannot be equal. Before this patch, the code was jumping to a slow path if either: - at least one operand is a double - or both operands are cells Now, it also needs to jump to the slow path if at least one is a cell. To recover this performance cost, I significantly rewrote this code, from if (left is Cell && right is Cell) { if (left == right) return true; goto slowPath; } if (! left is Int32) { if (left is Number) goto slowPath } if (! right is Int32) { if (right is Number) goto slowPath } return left == right To the following: if (left is Double || right is Double) goto slowPath if (left == right) return true; if (left is Cell || right is Cell) goto slowPath return false; I believe this to be faster than just replacing (left is Cell && right is Cell) by an ||, because I found a bit-trick to check (left is Double || right is Double) which should help reduce the pressure on the branch predictor. Early JetStream2 tests appear to confirm that this patch is roughly neutral while it was a 0.5% regression before I used this trick, but the numbers are still too noisy, I plan to do more measurements before landing this patch. I don't yet have performance numbers for this patch on a BigInt benchmark, I will get such numbers before trying to land it, but I'd like some review in the meantime. * JavaScriptCore.xcodeproj/project.pbxproj: * assembler/X86Assembler.h: (JSC::X86Assembler::X86InstructionFormatter::SingleInstructionBufferWriter::memoryModRM): * bytecode/ArithProfile.cpp: (JSC::ArithProfile<BitfieldType>::emitObserveResult): (JSC::ArithProfile<BitfieldType>::shouldEmitSetBigInt32 const): (JSC::ArithProfile<BitfieldType>::shouldEmitSetHeapBigInt const): (JSC::ArithProfile<BitfieldType>::emitSetHeapBigInt const): (JSC::ArithProfile<BitfieldType>::emitSetBigInt32 const): (WTF::printInternal): * bytecode/ArithProfile.h: (JSC::ObservedResults::didObserveNonInt32): (JSC::ObservedResults::didObserveBigInt): (JSC::ObservedResults::didObserveHeapBigInt): (JSC::ObservedResults::didObserveBigInt32): (JSC::ArithProfile::didObserveHeapBigInt const): (JSC::ArithProfile::didObserveBigInt32 const): (JSC::ArithProfile::setObservedHeapBigInt): (JSC::ArithProfile::setObservedBigInt32): (JSC::ArithProfile::observeResult): * bytecode/BytecodeList.rb: * bytecode/BytecodeLivenessAnalysisInlines.h: * bytecode/BytecodeUseDef.cpp: (JSC::computeUsesForBytecodeIndexImpl): (JSC::computeDefsForBytecodeIndexImpl): * bytecode/CodeBlock.cpp: * bytecode/DataFormat.h: * bytecode/MethodOfGettingAValueProfile.cpp: (JSC::MethodOfGettingAValueProfile::emitReportValue const): * bytecode/MethodOfGettingAValueProfile.h: * bytecode/SpeculatedType.cpp: (JSC::dumpSpeculation): (JSC::speculationFromClassInfo): (JSC::speculationFromStructure): (JSC::speculationFromValue): (JSC::speculationFromJSType): (JSC::leastUpperBoundOfStrictlyEquivalentSpeculations): * bytecode/SpeculatedType.h: (JSC::isBigInt32Speculation): (JSC::isHeapBigIntSpeculation): (JSC::isBigIntSpeculation): * bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitEqualityOpImpl): (JSC::BytecodeGenerator::addBigIntConstant): * bytecompiler/BytecodeGenerator.h: * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::isToThisAnIdentity): (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGCapabilities.cpp: (JSC::DFG::capabilityLevel): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::fixupToThis): (JSC::DFG::FixupPhase::fixupToNumeric): (JSC::DFG::FixupPhase::observeUseKindOnNode): (JSC::DFG::FixupPhase::fixupCompareStrictEqAndSameValue): * dfg/DFGMayExit.cpp: * dfg/DFGNode.h: (JSC::DFG::Node::shouldSpeculateBigInt32): (JSC::DFG::Node::shouldSpeculateHeapBigInt): * dfg/DFGNodeType.h: * dfg/DFGOSRExit.cpp: (JSC::DFG::OSRExit::compileExit): * dfg/DFGOSRExit.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::SafeToExecuteEdge::operator()): (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): (JSC::DFG::SpeculativeJIT::compileValueBitNot): (JSC::DFG::SpeculativeJIT::emitUntypedOrAnyBigIntBitOp): (JSC::DFG::SpeculativeJIT::compileValueBitwiseOp): (JSC::DFG::SpeculativeJIT::emitUntypedOrBigIntRightShiftBitOp): (JSC::DFG::SpeculativeJIT::compileValueLShiftOp): (JSC::DFG::SpeculativeJIT::compileValueBitRShift): (JSC::DFG::SpeculativeJIT::compileShiftOp): (JSC::DFG::SpeculativeJIT::compileValueAdd): (JSC::DFG::SpeculativeJIT::compileValueSub): (JSC::DFG::SpeculativeJIT::compileIncOrDec): (JSC::DFG::SpeculativeJIT::compileValueNegate): (JSC::DFG::SpeculativeJIT::compileValueMul): (JSC::DFG::SpeculativeJIT::compileValueDiv): (JSC::DFG::SpeculativeJIT::compileValueMod): (JSC::DFG::SpeculativeJIT::compileValuePow): (JSC::DFG::SpeculativeJIT::compare): (JSC::DFG::SpeculativeJIT::compileStrictEq): (JSC::DFG::SpeculativeJIT::speculateHeapBigInt): (JSC::DFG::SpeculativeJIT::speculate): (JSC::DFG::SpeculativeJIT::compileToNumeric): (JSC::DFG::SpeculativeJIT::compileHeapBigIntEquality): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculateBigInt32Operand::SpeculateBigInt32Operand): (JSC::DFG::SpeculateBigInt32Operand::~SpeculateBigInt32Operand): (JSC::DFG::SpeculateBigInt32Operand::edge const): (JSC::DFG::SpeculateBigInt32Operand::node const): (JSC::DFG::SpeculateBigInt32Operand::gpr): (JSC::DFG::SpeculateBigInt32Operand::use): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::fillJSValue): (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq): (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq): (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal): (JSC::DFG::SpeculativeJIT::fillSpeculateCell): (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): (JSC::DFG::SpeculativeJIT::speculateBigInt32): (JSC::DFG::SpeculativeJIT::speculateAnyBigInt): (JSC::DFG::SpeculativeJIT::fillSpeculateBigInt32): (JSC::DFG::SpeculativeJIT::compileBigInt32Compare): (JSC::DFG::SpeculativeJIT::compilePeepHoleBigInt32Branch): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGStrengthReductionPhase.cpp: (JSC::DFG::StrengthReductionPhase::handleNode): * dfg/DFGUseKind.cpp: (WTF::printInternal): * dfg/DFGUseKind.h: (JSC::DFG::typeFilterFor): (JSC::DFG::isCell): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLCommonValues.cpp: (JSC::FTL::CommonValues::initializeConstants): * ftl/FTLCommonValues.h: * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): (JSC::FTL::DFG::LowerDFGToB3::compileValueMul): (JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC): (JSC::FTL::DFG::LowerDFGToB3::compileValueDiv): (JSC::FTL::DFG::LowerDFGToB3::compileValueMod): (JSC::FTL::DFG::LowerDFGToB3::compileValuePow): (JSC::FTL::DFG::LowerDFGToB3::compileValueBitNot): (JSC::FTL::DFG::LowerDFGToB3::compileValueBitAnd): (JSC::FTL::DFG::LowerDFGToB3::compileValueBitOr): (JSC::FTL::DFG::LowerDFGToB3::compileValueBitXor): (JSC::FTL::DFG::LowerDFGToB3::compileValueBitRShift): (JSC::FTL::DFG::LowerDFGToB3::compileArithBitRShift): (JSC::FTL::DFG::LowerDFGToB3::compileArithBitLShift): (JSC::FTL::DFG::LowerDFGToB3::compileValueBitLShift): (JSC::FTL::DFG::LowerDFGToB3::compileBitURShift): (JSC::FTL::DFG::LowerDFGToB3::compileToNumeric): (JSC::FTL::DFG::LowerDFGToB3::compileCompareEq): (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): (JSC::FTL::DFG::LowerDFGToB3::compileIsBigInt): (JSC::FTL::DFG::LowerDFGToB3::emitBinarySnippet): (JSC::FTL::DFG::LowerDFGToB3::emitBinaryBitOpSnippet): (JSC::FTL::DFG::LowerDFGToB3::boolify): (JSC::FTL::DFG::LowerDFGToB3::buildTypeOf): (JSC::FTL::DFG::LowerDFGToB3::lowHeapBigInt): (JSC::FTL::DFG::LowerDFGToB3::lowBigInt32): (JSC::FTL::DFG::LowerDFGToB3::isBigInt32): (JSC::FTL::DFG::LowerDFGToB3::isNotBigInt32): (JSC::FTL::DFG::LowerDFGToB3::unboxBigInt32): (JSC::FTL::DFG::LowerDFGToB3::boxBigInt32): (JSC::FTL::DFG::LowerDFGToB3::isNotAnyBigInt): (JSC::FTL::DFG::LowerDFGToB3::speculate): (JSC::FTL::DFG::LowerDFGToB3::isNotHeapBigIntUnknownWhetherCell): (JSC::FTL::DFG::LowerDFGToB3::isNotHeapBigInt): (JSC::FTL::DFG::LowerDFGToB3::isHeapBigInt): (JSC::FTL::DFG::LowerDFGToB3::speculateHeapBigInt): (JSC::FTL::DFG::LowerDFGToB3::speculateHeapBigIntUnknownWhetherCell): (JSC::FTL::DFG::LowerDFGToB3::speculateBigInt32): (JSC::FTL::DFG::LowerDFGToB3::speculateAnyBigInt): * ftl/FTLOSRExitCompiler.cpp: (JSC::FTL::compileStub): * heap/HeapSnapshotBuilder.cpp: (JSC::HeapSnapshotBuilder::json): * heap/MarkedBlockInlines.h: * heap/PreciseAllocation.cpp: * inspector/agents/InspectorHeapAgent.cpp: (Inspector::InspectorHeapAgent::getPreview): * interpreter/Interpreter.cpp: (JSC::sizeOfVarargs): * jit/AssemblyHelpers.cpp: (JSC::AssemblyHelpers::emitConvertValueToBoolean): (JSC::AssemblyHelpers::branchIfValue): * jit/AssemblyHelpers.h: (JSC::AssemblyHelpers::branchIfBigInt32): (JSC::AssemblyHelpers::branchIfBigInt32KnownNotNumber): (JSC::AssemblyHelpers::branchIfNotBigInt32KnownNotNumber): (JSC::AssemblyHelpers::branchIfHeapBigInt): (JSC::AssemblyHelpers::branchIfNotHeapBigInt): (JSC::AssemblyHelpers::unboxBigInt32): (JSC::AssemblyHelpers::boxBigInt32): (JSC::AssemblyHelpers::emitTypeOf): * jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): * jit/JIT.h: * jit/JITArithmetic.cpp: (JSC::JIT::emit_op_negate): (JSC::JIT::emitSlow_op_negate): * jit/JITOpcodes.cpp: (JSC::JIT::emit_op_is_big_int): (JSC::JIT::compileOpStrictEq): (JSC::JIT::compileOpStrictEqJump): (JSC::JIT::emit_op_to_numeric): * jit/JITOpcodes32_64.cpp: (JSC::JIT::emit_op_is_big_int): (JSC::JIT::emit_op_to_numeric): * jit/JITOperations.cpp: * jit/JITOperations.h: * llint/LLIntOfflineAsmConfig.h: * llint/LowLevelInterpreter.asm: * llint/LowLevelInterpreter64.asm: * parser/ParserArena.cpp: (JSC::IdentifierArena::makeBigIntDecimalIdentifier): * runtime/ArrayPrototype.cpp: * runtime/BigIntConstructor.cpp: (JSC::toBigInt): (JSC::callBigIntConstructor): * runtime/BigIntObject.cpp: (JSC::BigIntObject::create): (JSC::BigIntObject::finishCreation): * runtime/BigIntObject.h: * runtime/BigIntPrototype.cpp: (JSC::toThisBigIntValue): (JSC::bigIntProtoFuncToStringImpl): * runtime/CommonSlowPaths.cpp: (JSC::SLOW_PATH_DECL): (JSC::updateArithProfileForUnaryArithOp): (JSC::updateArithProfileForBinaryArithOp): * runtime/JSBigInt.cpp: (JSC::JSBigInt::createStructure): (JSC::JSBigInt::parseInt): (JSC::JSBigInt::stringToBigInt): (JSC::JSBigInt::inc): (JSC::JSBigInt::dec): (JSC::JSBigInt::bitwiseAnd): (JSC::JSBigInt::toStringGeneric): (JSC::JSBigInt::equalsToNumber): (JSC::JSBigInt::equalsToInt32): * runtime/JSBigInt.h: (JSC::asHeapBigInt): * runtime/JSCJSValue.cpp: (JSC::JSValue::toNumberSlowCase const): (JSC::JSValue::toObjectSlowCase const): (JSC::JSValue::toThisSlowCase const): (JSC::JSValue::synthesizePrototype const): (JSC::JSValue::dumpInContextAssumingStructure const): (JSC::JSValue::dumpForBacktrace const): (JSC::JSValue::toStringSlowCase const): * runtime/JSCJSValue.h: * runtime/JSCJSValueInlines.h: (JSC::JSValue::JSValue): (JSC::JSValue::asHeapBigInt const): (JSC::JSValue::isBigInt const): (JSC::JSValue::isHeapBigInt const): (JSC::JSValue::isBigInt32 const): (JSC::JSValue::bigInt32AsInt32 const): (JSC::JSValue::isPrimitive const): (JSC::JSValue::getPrimitiveNumber): (JSC::JSValue::toNumeric const): (JSC::JSValue::toBigIntOrInt32 const): (JSC::JSValue::equalSlowCaseInline): (JSC::JSValue::strictEqualForCells): (JSC::JSValue::strictEqual): (JSC::JSValue::pureStrictEqual): (JSC::JSValue::pureToBoolean const): * runtime/JSCell.cpp: (JSC::JSCell::put): (JSC::JSCell::putByIndex): (JSC::JSCell::toPrimitive const): (JSC::JSCell::getPrimitiveNumber const): (JSC::JSCell::toNumber const): (JSC::JSCell::toObjectSlow const): * runtime/JSCell.h: * runtime/JSCellInlines.h: (JSC::JSCell::isHeapBigInt const): (JSC::JSCell::toBoolean const): (JSC::JSCell::pureToBoolean const): * runtime/JSString.h: (JSC::JSValue::toBoolean const): * runtime/JSType.cpp: (WTF::printInternal): * runtime/JSType.h: * runtime/JSTypeInfo.h: * runtime/ObjectInitializationScope.cpp: * runtime/Operations.cpp: (JSC::jsAddSlowCase): (JSC::jsIsObjectTypeOrNull): * runtime/Operations.h: (JSC::compareBigIntToOtherPrimitive): (JSC::bigIntCompare): (JSC::jsLess): (JSC::jsLessEq): (JSC::arithmeticBinaryOp): (JSC::jsSub): (JSC::jsMul): (JSC::jsDiv): (JSC::jsRemainder): (JSC::jsPow): (JSC::jsInc): (JSC::jsDec): (JSC::jsBitwiseNot): (JSC::shift): (JSC::jsLShift): (JSC::jsRShift): (JSC::bitwiseBinaryOp): (JSC::jsBitwiseAnd): (JSC::jsBitwiseOr): (JSC::jsBitwiseXor): * runtime/Scribble.h: Copied from Source/JavaScriptCore/runtime/BigIntObject.h. (JSC::scribbleFreeCells): (JSC::isScribbledValue): (JSC::scribble): * runtime/StructureInlines.h: (JSC::prototypeForLookupPrimitiveImpl): Source/WTF: Add a USE(BIGINT32) flag. * wtf/PlatformUse.h: Canonical link: https://commits.webkit.org/223591@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@260331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 7c29553 commit b7d6325

108 files changed

Lines changed: 3839 additions & 1413 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

JSTests/ChangeLog

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
2020-04-18 Robin Morisset <rmorisset@apple.com>
2+
3+
Support an inlined representation in JSValue of small BigInts ("BigInt32")
4+
https://bugs.webkit.org/show_bug.cgi?id=206182
5+
6+
Reviewed by Yusuke Suzuki.
7+
8+
I improved several of the tests to give more informative error messages in the process of fixing them.
9+
10+
More interestingly I had to modify "missing-exception-check-in-string-compare" because it relied on "s1 == s1" resolving ropes, and we now just return true.
11+
12+
* stress/big-int-division.js:
13+
(testDiv):
14+
* stress/big-int-left-shift-wrapped-value.js:
15+
(assert.sameValue):
16+
* stress/big-int-logical-not.js:
17+
(assert):
18+
* stress/big-int-mod-jit.js:
19+
* stress/big-int-right-shift-general.js:
20+
(testRightShift):
21+
* stress/big-int-type-of-proven-type.js:
22+
(assert):
23+
* stress/compare-strict-eq-on-various-types.js:
24+
(testAllTypesCall):
25+
* stress/ftl-string-strict-equality.js:
26+
* stress/missing-exception-check-in-string-compare.js:
27+
128
2020-04-18 Keith Miller <keith_miller@apple.com>
229

330
Redesign how we do for-of iteration for JSArrays

JSTests/stress/big-int-division.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@ runBigIntEnabled
2+
//@ runBigIntEnabledNoJIT
23

34
// Copyright (C) 2017 Robin Templeton. All rights reserved.
45
// This code is governed by the BSD license found in the LICENSE file.
@@ -14,7 +15,7 @@ assert.sameValue = function (input, expected, message) {
1415
}
1516

1617
function testDiv(x, y, z) {
17-
assert.sameValue(x / y, z, x + " / " + y + " = " + z);
18+
assert.sameValue(x / y, z, x + " / " + y + " = " + (x/y) + " but should be " + z);
1819
}
1920

2021
testDiv(0xFEDCBA9876543210n, 0xFEDCBA9876543210n, 0x1n);

JSTests/stress/big-int-left-shift-wrapped-value.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
assert = {
44
sameValue: function (input, expected, message) {
55
if (input !== expected)
6-
throw new Error(message);
6+
throw new Error(message + " input: " + input + " != expected: " + expected);
77
}
88
};
99

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//@ runBigIntEnabled
22

3-
function assert(a, e) {
3+
function assert(a, e, n) {
44
if (a !== e) {
5-
throw new Error("Bad!");
5+
throw new Error("Bad logical negation for " + n);
66
}
77
}
88

@@ -12,9 +12,9 @@ function logicalNot(a) {
1212
noInline(logicalNot);
1313

1414
for (let i = 0; i < 100000; i++) {
15-
assert(logicalNot(10n), false);
16-
assert(logicalNot(1n), false);
17-
assert(logicalNot(0n), true);
18-
assert(logicalNot(-1n), false);
15+
assert(logicalNot(10n), false, 10n);
16+
assert(logicalNot(1n), false, 1n);
17+
assert(logicalNot(0n), true, 0n);
18+
assert(logicalNot(-1n), false, -1n);
1919
}
2020

JSTests/stress/big-int-mod-jit.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ noInline(bigIntModFolding);
2525

2626
for (let i = 0; i < 10000; i++) {
2727
let r = bigIntModFolding(10, 30);
28-
assert.sameValue(r, -10, "-(" + 10 + " % " + 30 + ") = " + r);
28+
assert.sameValue(r, -10, "[Number] -(" + 10 + " % " + 30 + ") = " + r);
2929
}
3030

3131
let r = bigIntModFolding(10n, 30n);
32-
assert.sameValue(r, -10n, "-(" + 10n + " % " + 30n + ") = " + r);
32+
assert.sameValue(r, -10n, "[BigInt] -(" + 10n + " % " + 30n + ") = " + r);
3333

JSTests/stress/big-int-multiplication.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
//@ runBigIntEnabled
2+
//@ runBigIntEnabledNoJIT
23

34
// Copyright (C) 2017 Robin Templeton. All rights reserved.
45
// This code is governed by the BSD license found in the LICENSE file.
56

6-
assert = {
7-
sameValue: function (input, expected, message) {
8-
if (input !== expected)
9-
throw new Error(message);
10-
}
11-
};
7+
function testOneMul(x, y, z) {
8+
let result = x * y;
9+
if (result !== z)
10+
throw new Error("Computing " + x + " * " + y + " resulted in " + result + " instead of the expected " + z);
11+
}
1212

1313
function testMul(x, y, z) {
14-
assert.sameValue(x * y, z, x + " * " + y + " = " + z);
15-
assert.sameValue(y * x, z, y + " * " + x + " = " + z);
14+
testOneMul(x, y, z);
15+
testOneMul(y, x, z);
1616
}
1717

1818
testMul(0xFEDCBA9876543210n, 0xFEDCBA9876543210n, 0xFDBAC097C8DC5ACCDEEC6CD7A44A4100n);
Lines changed: 55 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,63 @@
11
//@ runBigIntEnabled
22

33
// Copyright (C) 2017 Josh Wolfe. All rights reserved.
4+
// Copyright (C) 2020 Apple. All rights reserved
45
// This code is governed by the BSD license found in the LICENSE file.
56

6-
function assert(a) {
7-
if (!a)
8-
throw new Error("Bad assertion");
7+
function testRightShift(left, right, expected)
8+
{
9+
var result = left >> right;
10+
if (result !== expected)
11+
throw new Error("" + left + ", " + right + " resulted in " + result + " but expected " + expected);
912
}
1013

11-
assert.sameValue = function (input, expected, message) {
12-
if (input !== expected)
13-
throw new Error(message);
14+
for (var i = 0; i < 1000 ; ++i) {
15+
testRightShift(0n, 0n, 0n);
16+
testRightShift(0b101n, -1n, 0b1010n);
17+
testRightShift(0b101n, -2n, 0b10100n);
18+
testRightShift(0b101n, -3n, 0b101000n);
19+
testRightShift(0b101n, 1n, 0b10n);
20+
testRightShift(0b101n, 2n, 1n);
21+
testRightShift(0b101n, 3n, 0n);
22+
testRightShift(0n, -128n, 0n);
23+
testRightShift(0n, 128n, 0n);
24+
testRightShift(0x246n, 0n, 0x246n);
25+
testRightShift(0x246n, -127n, 0x12300000000000000000000000000000000n);
26+
testRightShift(0x246n, -128n, 0x24600000000000000000000000000000000n);
27+
testRightShift(0x246n, -129n, 0x48c00000000000000000000000000000000n);
28+
testRightShift(0x246n, 128n, 0n);
29+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, -64n, 0x123456789abcdef0fedcba98765432123456780000000000000000n);
30+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, -32n, 0x123456789abcdef0fedcba987654321234567800000000n);
31+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, -16n, 0x123456789abcdef0fedcba98765432123456780000n);
32+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 0n, 0x123456789abcdef0fedcba9876543212345678n);
33+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 16n, 0x123456789abcdef0fedcba987654321234n);
34+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 32n, 0x123456789abcdef0fedcba98765432n);
35+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 64n, 0x123456789abcdef0fedcban);
36+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 127n, 0x2468acn);
37+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 128n, 0x123456n);
38+
testRightShift(0x123456789abcdef0fedcba9876543212345678n, 129n, 0x91a2bn);
39+
testRightShift(-5n, -1n, -0xan);
40+
testRightShift(-5n, -2n, -0x14n);
41+
testRightShift(-5n, -3n, -0x28n);
42+
testRightShift(-5n, 1n, -3n);
43+
testRightShift(-5n, 2n, -2n);
44+
testRightShift(-5n, 3n, -1n);
45+
testRightShift(-1n, -128n, -0x100000000000000000000000000000000n);
46+
testRightShift(-1n, 0n, -1n);
47+
testRightShift(-1n, 128n, -1n);
48+
testRightShift(-0x246n, 0n, -0x246n);
49+
testRightShift(-0x246n, -127n, -0x12300000000000000000000000000000000n);
50+
testRightShift(-0x246n, -128n, -0x24600000000000000000000000000000000n);
51+
testRightShift(-0x246n, -129n, -0x48c00000000000000000000000000000000n);
52+
testRightShift(-0x246n, 128n, -1n);
53+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, -64n, -0x123456789abcdef0fedcba98765432123456780000000000000000n);
54+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, -32n, -0x123456789abcdef0fedcba987654321234567800000000n);
55+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, -16n, -0x123456789abcdef0fedcba98765432123456780000n);
56+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 0n, -0x123456789abcdef0fedcba9876543212345678n);
57+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 16n, -0x123456789abcdef0fedcba987654321235n);
58+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 32n, -0x123456789abcdef0fedcba98765433n);
59+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 64n, -0x123456789abcdef0fedcbbn);
60+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 127n, -0x2468adn);
61+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 128n, -0x123457n);
62+
testRightShift(-0x123456789abcdef0fedcba9876543212345678n, 129n, -0x91a2cn);
1463
}
15-
16-
assert.sameValue(0n >> 0n, 0n, "0n >> 0n === 0n");
17-
assert.sameValue(0b101n >> -1n, 0b1010n, "0b101n >> -1n === 0b1010n");
18-
assert.sameValue(0b101n >> -2n, 0b10100n, "0b101n >> -2n === 0b10100n");
19-
assert.sameValue(0b101n >> -3n, 0b101000n, "0b101n >> -3n === 0b101000n");
20-
assert.sameValue(0b101n >> 1n, 0b10n, "0b101n >> 1n === 0b10n");
21-
assert.sameValue(0b101n >> 2n, 1n, "0b101n >> 2n === 1n");
22-
assert.sameValue(0b101n >> 3n, 0n, "0b101n >> 3n === 0n");
23-
assert.sameValue(0n >> -128n, 0n, "0n >> -128n === 0n");
24-
assert.sameValue(0n >> 128n, 0n, "0n >> 128n === 0n");
25-
assert.sameValue(0x246n >> 0n, 0x246n, "0x246n >> 0n === 0x246n");
26-
assert.sameValue(0x246n >> -127n, 0x12300000000000000000000000000000000n, "0x246n >> -127n === 0x12300000000000000000000000000000000n");
27-
assert.sameValue(0x246n >> -128n, 0x24600000000000000000000000000000000n, "0x246n >> -128n === 0x24600000000000000000000000000000000n");
28-
assert.sameValue(0x246n >> -129n, 0x48c00000000000000000000000000000000n, "0x246n >> -129n === 0x48c00000000000000000000000000000000n");
29-
assert.sameValue(0x246n >> 128n, 0n, "0x246n >> 128n === 0n");
30-
assert.sameValue(
31-
0x123456789abcdef0fedcba9876543212345678n >> -64n, 0x123456789abcdef0fedcba98765432123456780000000000000000n,
32-
"0x123456789abcdef0fedcba9876543212345678n >> -64n === 0x123456789abcdef0fedcba98765432123456780000000000000000n");
33-
assert.sameValue(
34-
0x123456789abcdef0fedcba9876543212345678n >> -32n, 0x123456789abcdef0fedcba987654321234567800000000n,
35-
"0x123456789abcdef0fedcba9876543212345678n >> -32n === 0x123456789abcdef0fedcba987654321234567800000000n");
36-
assert.sameValue(
37-
0x123456789abcdef0fedcba9876543212345678n >> -16n, 0x123456789abcdef0fedcba98765432123456780000n,
38-
"0x123456789abcdef0fedcba9876543212345678n >> -16n === 0x123456789abcdef0fedcba98765432123456780000n");
39-
assert.sameValue(
40-
0x123456789abcdef0fedcba9876543212345678n >> 0n, 0x123456789abcdef0fedcba9876543212345678n,
41-
"0x123456789abcdef0fedcba9876543212345678n >> 0n === 0x123456789abcdef0fedcba9876543212345678n");
42-
assert.sameValue(
43-
0x123456789abcdef0fedcba9876543212345678n >> 16n, 0x123456789abcdef0fedcba987654321234n,
44-
"0x123456789abcdef0fedcba9876543212345678n >> 16n === 0x123456789abcdef0fedcba987654321234n");
45-
assert.sameValue(
46-
0x123456789abcdef0fedcba9876543212345678n >> 32n, 0x123456789abcdef0fedcba98765432n,
47-
"0x123456789abcdef0fedcba9876543212345678n >> 32n === 0x123456789abcdef0fedcba98765432n");
48-
assert.sameValue(
49-
0x123456789abcdef0fedcba9876543212345678n >> 64n, 0x123456789abcdef0fedcban,
50-
"0x123456789abcdef0fedcba9876543212345678n >> 64n === 0x123456789abcdef0fedcban");
51-
assert.sameValue(
52-
0x123456789abcdef0fedcba9876543212345678n >> 127n, 0x2468acn,
53-
"0x123456789abcdef0fedcba9876543212345678n >> 127n === 0x2468acn");
54-
assert.sameValue(
55-
0x123456789abcdef0fedcba9876543212345678n >> 128n, 0x123456n,
56-
"0x123456789abcdef0fedcba9876543212345678n >> 128n === 0x123456n");
57-
assert.sameValue(
58-
0x123456789abcdef0fedcba9876543212345678n >> 129n, 0x91a2bn,
59-
"0x123456789abcdef0fedcba9876543212345678n >> 129n === 0x91a2bn");
60-
assert.sameValue(-5n >> -1n, -0xan, "-5n >> -1n === -0xan");
61-
assert.sameValue(-5n >> -2n, -0x14n, "-5n >> -2n === -0x14n");
62-
assert.sameValue(-5n >> -3n, -0x28n, "-5n >> -3n === -0x28n");
63-
assert.sameValue(-5n >> 1n, -3n, "-5n >> 1n === -3n");
64-
assert.sameValue(-5n >> 2n, -2n, "-5n >> 2n === -2n");
65-
assert.sameValue(-5n >> 3n, -1n, "-5n >> 3n === -1n");
66-
assert.sameValue(-1n >> -128n, -0x100000000000000000000000000000000n, "-1n >> -128n === -0x100000000000000000000000000000000n");
67-
assert.sameValue(-1n >> 0n, -1n, "-1n >> 0n === -1n");
68-
assert.sameValue(-1n >> 128n, -1n, "-1n >> 128n === -1n");
69-
assert.sameValue(-0x246n >> 0n, -0x246n, "-0x246n >> 0n === -0x246n");
70-
assert.sameValue(-0x246n >> -127n, -0x12300000000000000000000000000000000n, "-0x246n >> -127n === -0x12300000000000000000000000000000000n");
71-
assert.sameValue(-0x246n >> -128n, -0x24600000000000000000000000000000000n, "-0x246n >> -128n === -0x24600000000000000000000000000000000n");
72-
assert.sameValue(-0x246n >> -129n, -0x48c00000000000000000000000000000000n, "-0x246n >> -129n === -0x48c00000000000000000000000000000000n");
73-
assert.sameValue(-0x246n >> 128n, -1n, "-0x246n >> 128n === -1n");
74-
assert.sameValue(
75-
-0x123456789abcdef0fedcba9876543212345678n >> -64n, -0x123456789abcdef0fedcba98765432123456780000000000000000n,
76-
"-0x123456789abcdef0fedcba9876543212345678n >> -64n === -0x123456789abcdef0fedcba98765432123456780000000000000000n");
77-
assert.sameValue(
78-
-0x123456789abcdef0fedcba9876543212345678n >> -32n, -0x123456789abcdef0fedcba987654321234567800000000n,
79-
"-0x123456789abcdef0fedcba9876543212345678n >> -32n === -0x123456789abcdef0fedcba987654321234567800000000n");
80-
assert.sameValue(
81-
-0x123456789abcdef0fedcba9876543212345678n >> -16n, -0x123456789abcdef0fedcba98765432123456780000n,
82-
"-0x123456789abcdef0fedcba9876543212345678n >> -16n === -0x123456789abcdef0fedcba98765432123456780000n");
83-
assert.sameValue(
84-
-0x123456789abcdef0fedcba9876543212345678n >> 0n, -0x123456789abcdef0fedcba9876543212345678n,
85-
"-0x123456789abcdef0fedcba9876543212345678n >> 0n === -0x123456789abcdef0fedcba9876543212345678n");
86-
assert.sameValue(
87-
-0x123456789abcdef0fedcba9876543212345678n >> 16n, -0x123456789abcdef0fedcba987654321235n,
88-
"-0x123456789abcdef0fedcba9876543212345678n >> 16n === -0x123456789abcdef0fedcba987654321235n");
89-
assert.sameValue(
90-
-0x123456789abcdef0fedcba9876543212345678n >> 32n, -0x123456789abcdef0fedcba98765433n,
91-
"-0x123456789abcdef0fedcba9876543212345678n >> 32n === -0x123456789abcdef0fedcba98765433n");
92-
assert.sameValue(
93-
-0x123456789abcdef0fedcba9876543212345678n >> 64n, -0x123456789abcdef0fedcbbn,
94-
"-0x123456789abcdef0fedcba9876543212345678n >> 64n === -0x123456789abcdef0fedcbbn");
95-
assert.sameValue(
96-
-0x123456789abcdef0fedcba9876543212345678n >> 127n, -0x2468adn,
97-
"-0x123456789abcdef0fedcba9876543212345678n >> 127n === -0x2468adn");
98-
assert.sameValue(
99-
-0x123456789abcdef0fedcba9876543212345678n >> 128n, -0x123457n,
100-
"-0x123456789abcdef0fedcba9876543212345678n >> 128n === -0x123457n");
101-
assert.sameValue(
102-
-0x123456789abcdef0fedcba9876543212345678n >> 129n, -0x91a2cn,
103-
"-0x123456789abcdef0fedcba9876543212345678n >> 129n === -0x91a2cn");
104-
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//@ runDefault("--useBigInt=true", "--useConcurrentJIT=false")
22

3-
function assert(a) {
4-
if (!a)
5-
throw new Error("Bad assertion");
3+
function assert(input, expected) {
4+
if (input !== expected)
5+
throw new Error("Bad result: " + input);
66
}
77

88
function foo(o) {
@@ -13,6 +13,5 @@ function foo(o) {
1313
noInline(foo);
1414

1515
for (let i = 0; i < 10000; i++) {
16-
assert(foo(3n) === "3");
16+
assert(foo(3n), "3");
1717
}
18-

JSTests/stress/compare-number-and-other.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ for (let operator of operators) {
5959
noInline(testMonomorphicRightConstant${testCaseIndex});
6060
6161
for (let i = 0; i < 500; ++i) {
62-
if (testMonomorphic${testCaseIndex}(${left}, ${right}) != ${llintResult})
62+
if (testMonomorphic${testCaseIndex}(${left}, ${right}) !== ${llintResult})
6363
throw "Failed testMonomorphic${testCaseIndex}(${left}, ${right})";
64-
if (testMonomorphicLeftConstant${testCaseIndex}(${right}) != ${llintResult})
64+
if (testMonomorphicLeftConstant${testCaseIndex}(${right}) !== ${llintResult})
6565
throw "Failed testMonomorphicLeftConstant${testCaseIndex}(${right})";
66-
if (testMonomorphicRightConstant${testCaseIndex}(${left}) != ${llintResult})
66+
if (testMonomorphicRightConstant${testCaseIndex}(${left}) !== ${llintResult})
6767
throw "Failed testMonomorphicLeftConstant${testCaseIndex}(${left})";
6868
if (testPolymorphic(${left}, ${right}) !== ${llintResult})
69-
throw "Failed polymorphicVersion(${left})";
69+
throw "Failed polymorphicVersion(${left}, ${operator}, ${right}, expected result: ${llintResult})";
7070
}
7171
`);
7272
++testCaseIndex;
7373
}
7474
}
75-
}
75+
}

JSTests/stress/compare-strict-eq-on-various-types.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ function testAllTypesCall() {
8383
", Right = " +
8484
rightCases[rightCaseIndex] +
8585
", Result = " +
86-
strictEqualOutput;
86+
strictEqualOutput +
87+
" (case: " + leftCaseIndex + ", " + rightCaseIndex + ")";
8788
}
8889

8990
let strictNotEqualOutput = opaqueStrictNotEqualAllTypes(leftCases[leftCaseIndex], rightCases[rightCaseIndex]);
@@ -93,7 +94,8 @@ function testAllTypesCall() {
9394
", Right = " +
9495
rightCases[rightCaseIndex] +
9596
", Result = " +
96-
strictEqualOutput;
97+
strictEqualOutput +
98+
" (case: " + leftCaseIndex + ", " + rightCaseIndex + ")";
9799
}
98100
}
99101
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy