[runtime] Remove useless IN builtin.
authorbmeurer <bmeurer@chromium.org>
Thu, 13 Aug 2015 12:39:03 +0000 (05:39 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 13 Aug 2015 12:39:21 +0000 (12:39 +0000)
Similar to DELETE, the IN builtin is just a thin wrapper for %HasElement
and %HasProperty anyway, and cannot be optimized, plus it had a weird
special fast case (which also involved at least one LOAD_IC plus some
intrinsic magic).

R=yangguo@chromium.org,jarin@chromium.org

Review URL: https://codereview.chromium.org/1295433002

Cr-Commit-Position: refs/heads/master@{#30154}

23 files changed:
src/builtins.h
src/compiler/js-generic-lowering.cc
src/compiler/js-intrinsic-lowering.cc
src/compiler/js-intrinsic-lowering.h
src/compiler/typer.cc
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/full-codegen.h
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/ppc/full-codegen-ppc.cc
src/full-codegen/x64/full-codegen-x64.cc
src/full-codegen/x87/full-codegen-x87.cc
src/hydrogen.cc
src/runtime.js
src/runtime/runtime-numbers.cc
src/runtime/runtime-object.cc
src/runtime/runtime.h
test/cctest/compiler/test-run-inlining.cc
test/cctest/compiler/test-run-intrinsics.cc
test/cctest/test-api.cc
test/unittests/compiler/js-intrinsic-lowering-unittest.cc

index 6ec618ada9b129905662187213868db4eb175973..816fc2b135be0df8b96c4c76e0a6c21dc0d573d7 100644 (file)
@@ -175,7 +175,6 @@ enum BuiltinExtraArguments {
   V(SAR_STRONG, 1)                         \
   V(SHR, 1)                                \
   V(SHR_STRONG, 1)                         \
-  V(IN, 1)                                 \
   V(INSTANCE_OF, 1)                        \
   V(CALL_NON_FUNCTION, 0)                  \
   V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0)   \
index bec199e0e399f7ce34cd25516f89f9d7d93f2396..6691c758f8651db5be0c7e8101a5629e9b048873 100644 (file)
@@ -437,7 +437,7 @@ void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
 
 
 void JSGenericLowering::LowerJSHasProperty(Node* node) {
-  ReplaceWithBuiltinCall(node, Builtins::IN, 2);
+  ReplaceWithRuntimeCall(node, Runtime::kHasProperty);
 }
 
 
index e82ac205ccf46d72b20022fd05f170db5445784c..4917953264fab7994f21728a30c9647efa96c740 100644 (file)
@@ -52,8 +52,6 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
       return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
     case Runtime::kInlineIsFunction:
       return ReduceIsInstanceType(node, JS_FUNCTION_TYPE);
-    case Runtime::kInlineIsNonNegativeSmi:
-      return ReduceIsNonNegativeSmi(node);
     case Runtime::kInlineIsRegExp:
       return ReduceIsInstanceType(node, JS_REGEXP_TYPE);
     case Runtime::kInlineIsSmi:
@@ -239,11 +237,6 @@ Reduction JSIntrinsicLowering::ReduceIsInstanceType(
 }
 
 
-Reduction JSIntrinsicLowering::ReduceIsNonNegativeSmi(Node* node) {
-  return Change(node, simplified()->ObjectIsNonNegativeSmi());
-}
-
-
 Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
   return Change(node, simplified()->ObjectIsSmi());
 }
index c14882c7341337ca52e35e49931c79ed87b74171..15e9b4053e7ef388d0b98de37317ce7e39ff3442 100644 (file)
@@ -41,7 +41,6 @@ class JSIntrinsicLowering final : public AdvancedReducer {
   Reduction ReduceIncrementStatsCounter(Node* node);
   Reduction ReduceIsMinusZero(Node* node);
   Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
-  Reduction ReduceIsNonNegativeSmi(Node* node);
   Reduction ReduceIsSmi(Node* node);
   Reduction ReduceJSValueGetValue(Node* node);
   Reduction ReduceMapGetInstanceType(Node* node);
index aabcf4b5a8fd71f192918160dc6987502dac3638..101712ba075c47e9a3b04ab7838061b37c35502f 100644 (file)
@@ -1535,7 +1535,6 @@ Bounds Typer::Visitor::TypeJSCallFunction(Node* node) {
 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
   switch (CallRuntimeParametersOf(node->op()).id()) {
     case Runtime::kInlineIsSmi:
-    case Runtime::kInlineIsNonNegativeSmi:
     case Runtime::kInlineIsArray:
     case Runtime::kInlineIsDate:
     case Runtime::kInlineIsTypedArray:
index d7a9bc3e5fc6cb4bc5be98dca3641ed22d2be982..27c362d939239977b3413079ef685331666b2eb9 100644 (file)
@@ -3350,27 +3350,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ NonNegativeSmiTst(r0);
-  Split(eq, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5086,7 +5065,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ LoadRoot(ip, Heap::kTrueValueRootIndex);
       __ cmp(r0, ip);
index 9e73340019ed82cf503bd33927ae1b5effb9fb83..c73c737e2ec3fe987ba4fd371df942dc1c932001 100644 (file)
@@ -3043,28 +3043,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  uint64_t sign_mask = V8_UINT64_C(1) << (kSmiShift + kSmiValueSize - 1);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ TestAndSplit(x0, kSmiTagMask | sign_mask, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -4791,7 +4769,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ CompareRoot(x0, Heap::kTrueValueRootIndex);
       Split(eq, if_true, if_false, fall_through);
index 846a6afecc5849db745e160dfe3c190892acccae..bb3e6fde6b3a1c8bab8e4a90a81ca4141b8132c7 100644 (file)
@@ -488,7 +488,6 @@ class FullCodeGenerator: public AstVisitor {
 
 #define FOR_EACH_FULL_CODE_INTRINSIC(F)   \
   F(IsSmi)                                \
-  F(IsNonNegativeSmi)                     \
   F(IsArray)                              \
   F(IsTypedArray)                         \
   F(IsRegExp)                             \
index 390a44be30c0acb0e922212ffd575ab76830fb35..a0f3b6f9bff65f07f18254dcbd7c3c74115f0e28 100644 (file)
@@ -3243,27 +3243,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ test(eax, Immediate(kSmiTagMask | 0x80000000));
-  Split(zero, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5025,7 +5004,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ cmp(eax, isolate()->factory()->true_value());
       Split(equal, if_true, if_false, fall_through);
index d3139a7d4ecf46b22cca766c416a767967aeb91d..0d655162f284fc1ad75978e0f3e930521f73378c 100644 (file)
@@ -3341,27 +3341,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ NonNegativeSmiTst(v0, at);
-  Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5111,7 +5090,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ LoadRoot(t0, Heap::kTrueValueRootIndex);
       Split(eq, v0, Operand(t0), if_true, if_false, fall_through);
index e8a46c3facdb05fa1a21db1194c3398473ccb6e9..1cb2f1066bd7edb9165563db2eb9f9c00e7151c9 100644 (file)
@@ -3342,27 +3342,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ NonNegativeSmiTst(v0, at);
-  Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5113,7 +5092,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ LoadRoot(a4, Heap::kTrueValueRootIndex);
       Split(eq, v0, Operand(a4), if_true, if_false, fall_through);
index c92d883ef50538e04a5ab26b1f4e8ab725e92eac..28edd47521c6477ce1149e72086b64df71eafea0 100644 (file)
@@ -3342,27 +3342,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
-                         &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ TestIfPositiveSmi(r3, r0);
-  Split(eq, if_true, if_false, fall_through, cr0);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5132,7 +5111,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ LoadRoot(ip, Heap::kTrueValueRootIndex);
       __ cmp(r3, ip);
index eda5207026b8fdff1484eb837f9252ace5646311..354b52bcf944516bb44a152a28975cefe79c41f1 100644 (file)
@@ -3235,27 +3235,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  Condition non_negative_smi = masm()->CheckNonNegativeSmi(rax);
-  Split(non_negative_smi, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5034,7 +5013,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ CompareRoot(rax, Heap::kTrueValueRootIndex);
       Split(equal, if_true, if_false, fall_through);
index 061954729b0add541f54d1815d6c293399bdc2ee..a7d4d50774f4a7c9e260c99ae5265ede0d70cf11 100644 (file)
@@ -3234,27 +3234,6 @@ void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
-  ZoneList<Expression*>* args = expr->arguments();
-  DCHECK(args->length() == 1);
-
-  VisitForAccumulatorValue(args->at(0));
-
-  Label materialize_true, materialize_false;
-  Label* if_true = NULL;
-  Label* if_false = NULL;
-  Label* fall_through = NULL;
-  context()->PrepareTest(&materialize_true, &materialize_false,
-                         &if_true, &if_false, &fall_through);
-
-  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
-  __ test(eax, Immediate(kSmiTagMask | 0x80000000));
-  Split(zero, if_true, if_false, fall_through);
-
-  context()->Plug(if_true, if_false);
-}
-
-
 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   DCHECK(args->length() == 1);
@@ -5042,7 +5021,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   switch (op) {
     case Token::IN:
       VisitForStackValue(expr->right());
-      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      __ CallRuntime(Runtime::kHasProperty, 2);
       PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
       __ cmp(eax, isolate()->factory()->true_value());
       Split(equal, if_true, if_false, fall_through);
index d5868f399f0cc02d72d497fa3309175b250d4c6c..efc47b6113a11fca96b221613115801159895283 100644 (file)
@@ -11360,11 +11360,10 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
     return ast_context()->ReturnInstruction(result, expr->id());
 
   } else if (op == Token::IN) {
-    HValue* function = AddLoadJSBuiltin(Builtins::IN);
     Add<HPushArguments>(left, right);
-    // TODO(olivf) InvokeFunction produces a check for the parameter count,
-    // even though we are certain to pass the correct number of arguments here.
-    HInstruction* result = New<HInvokeFunction>(function, 2);
+    HInstruction* result =
+        New<HCallRuntime>(isolate()->factory()->empty_string(),
+                          Runtime::FunctionForId(Runtime::kHasProperty), 2);
     return ast_context()->ReturnInstruction(result, expr->id());
   }
 
index f7c91d3cc20e4130c4c6b20c46fe1c94483de68c..25825d78131935a43c94a234d6c400e0c29f85c9 100644 (file)
@@ -44,7 +44,6 @@ var SAR;
 var SAR_STRONG;
 var SHR;
 var SHR_STRONG;
-var IN;
 var INSTANCE_OF;
 var CALL_NON_FUNCTION;
 var CALL_NON_FUNCTION_AS_CONSTRUCTOR;
@@ -483,21 +482,6 @@ SHR_STRONG = function SHR_STRONG(y) {
    -----------------------------
 */
 
-// ECMA-262, section 11.8.7, page 54.
-IN = function IN(x) {
-  if (!IS_SPEC_OBJECT(x)) {
-    throw %MakeTypeError(kInvalidInOperatorUse, this, x);
-  }
-  if (%_IsNonNegativeSmi(this)) {
-    if (IS_ARRAY(x) && %_HasFastPackedElements(x)) {
-      return this < x.length;
-    }
-    return %HasElement(x, this);
-  }
-  return %HasProperty(x, %$toName(this));
-}
-
-
 // ECMA-262, section 11.8.6, page 54. To make the implementation more
 // efficient, the return value should be zero if the 'this' is an
 // instance of F, and non-zero if not. This makes it possible to avoid
index 7e6712ad230614f648304c41bd63540d30ce2caa..ae2633c234496785b1bd1ca10793f6e968da88ba 100644 (file)
@@ -548,15 +548,6 @@ RUNTIME_FUNCTION(Runtime_IsSmi) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_IsNonNegativeSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsSmi() &&
-                                    Smi::cast(obj)->value() >= 0);
-}
-
-
 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
   SealHandleScope shs(isolate);
   DCHECK(args.length() == 0);
index 064e4c216291dc7d56261dc195a0db1d6d2f54ab..59aac4800b609abc6fb73f862c6cc37cdcfe19d9 100644 (file)
@@ -779,25 +779,36 @@ RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
 }
 
 
+// ES6 section 12.9.3, operator in.
 RUNTIME_FUNCTION(Runtime_HasProperty) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  DCHECK_EQ(2, args.length());
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 1);
 
-  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
-  if (!maybe.IsJust()) return isolate->heap()->exception();
-  return isolate->heap()->ToBoolean(maybe.FromJust());
-}
+  // Check that {object} is actually a receiver.
+  if (!object->IsJSReceiver()) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError(MessageTemplate::kInvalidInOperatorUse, key, object));
+  }
+  Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
 
+  // Check for fast element case.
+  uint32_t index = 0;
+  if (key->ToArrayIndex(&index)) {
+    Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
+    if (!maybe.IsJust()) return isolate->heap()->exception();
+    return isolate->heap()->ToBoolean(maybe.FromJust());
+  }
 
-RUNTIME_FUNCTION(Runtime_HasElement) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
+  // Convert {key} to a Name first.
+  Handle<Name> name;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+                                     Runtime::ToName(isolate, key));
 
-  Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
+  // Lookup property by {name} on {receiver}.
+  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name);
   if (!maybe.IsJust()) return isolate->heap()->exception();
   return isolate->heap()->ToBoolean(maybe.FromJust());
 }
index cb6f89e25f40392c34df60f7b8b728acda1e0bd7..3d822abf1c7b58994261d472210f46028b2240e0 100644 (file)
@@ -424,7 +424,6 @@ namespace internal {
   F(SmiLexicographicCompare, 2, 1)     \
   F(MaxSmi, 0, 1)                      \
   F(IsSmi, 1, 1)                       \
-  F(IsNonNegativeSmi, 1, 1)            \
   F(GetRootNaN, 0, 1)
 
 
@@ -454,7 +453,6 @@ namespace internal {
   F(DeleteProperty_Strict, 2, 1)                     \
   F(HasOwnProperty, 2, 1)                            \
   F(HasProperty, 2, 1)                               \
-  F(HasElement, 2, 1)                                \
   F(IsPropertyEnumerable, 2, 1)                      \
   F(GetPropertyNamesFast, 1, 1)                      \
   F(GetOwnPropertyNames, 2, 1)                       \
index 1b2559fc5f492fd077fcb00ef49ed9b717da17a4..5119bb73ee832cd1f0730869b8bfacba5343d2a9 100644 (file)
@@ -415,20 +415,6 @@ TEST(InlineIntrinsicIsSmi) {
 }
 
 
-TEST(InlineIntrinsicIsNonNegativeSmi) {
-  FunctionTester T(
-      "(function () {"
-      "  var x = 42;"
-      "  function bar(s,t) { return %_IsNonNegativeSmi(x); };"
-      "  return bar;"
-      "})();",
-      kInlineFlags);
-
-  InstallAssertInlineCountHelper(CcTest::isolate());
-  T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
-}
-
-
 TEST(InlineIntrinsicIsArray) {
   FunctionTester T(
       "(function () {"
index 1fa37748c6753d5e0b64705bc5cb0100088d0d1e..ce449075c0634dd0cafacbd59a1415d1ab529fe3 100644 (file)
@@ -128,18 +128,6 @@ TEST(IsMinusZero) {
 }
 
 
-TEST(IsNonNegativeSmi) {
-  FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })", flags);
-
-  T.CheckTrue(T.Val(1));
-  T.CheckFalse(T.Val(1.1));
-  T.CheckFalse(T.Val(-0.0));
-  T.CheckFalse(T.Val(-2));
-  T.CheckFalse(T.Val(-2.3));
-  T.CheckFalse(T.undefined());
-}
-
-
 TEST(IsObject) {
   FunctionTester T("(function(a) { return %_IsObject(a); })", flags);
 
index dad5d6caf5ca1e79d4e2924b998ce52b818c89c3..5b8417f7717ff0901ac0ad5fb079fc78ecc07d9e 100644 (file)
@@ -19298,8 +19298,7 @@ TEST(AccessCheckThrows) {
   CheckCorrectThrow("%DeleteProperty_Sloppy(other, '1')");
   CheckCorrectThrow("%DeleteProperty_Strict(other, '1')");
   CheckCorrectThrow("%HasOwnProperty(other, 'x')");
-  CheckCorrectThrow("%HasProperty(other, 'x')");
-  CheckCorrectThrow("%HasElement(other, 1)");
+  CheckCorrectThrow("%HasProperty('x', other)");
   CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')");
   // PROPERTY_ATTRIBUTES_NONE = 0
   CheckCorrectThrow("%DefineAccessorPropertyUnchecked("
index 92be4e43e0b129c3afaf713407004cc969baf1e8..99f45749608eadd5b040d273b15bd53ff8c551c8 100644 (file)
@@ -125,23 +125,6 @@ TEST_F(JSIntrinsicLoweringTest, InlineIsSmi) {
 }
 
 
-// -----------------------------------------------------------------------------
-// %_IsNonNegativeSmi
-
-
-TEST_F(JSIntrinsicLoweringTest, InlineIsNonNegativeSmi) {
-  Node* const input = Parameter(0);
-  Node* const context = Parameter(1);
-  Node* const effect = graph()->start();
-  Node* const control = graph()->start();
-  Reduction const r = Reduce(graph()->NewNode(
-      javascript()->CallRuntime(Runtime::kInlineIsNonNegativeSmi, 1), input,
-      context, effect, control));
-  ASSERT_TRUE(r.Changed());
-  EXPECT_THAT(r.replacement(), IsObjectIsNonNegativeSmi(input));
-}
-
-
 // -----------------------------------------------------------------------------
 // %_IsArray