Home | History | Annotate | Download | only in debug
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/debug/debug-evaluate.h"
      6 
      7 #include "src/accessors.h"
      8 #include "src/assembler-inl.h"
      9 #include "src/compiler.h"
     10 #include "src/contexts.h"
     11 #include "src/debug/debug-frames.h"
     12 #include "src/debug/debug-scopes.h"
     13 #include "src/debug/debug.h"
     14 #include "src/frames-inl.h"
     15 #include "src/globals.h"
     16 #include "src/interpreter/bytecode-array-iterator.h"
     17 #include "src/interpreter/bytecodes.h"
     18 #include "src/isolate-inl.h"
     19 #include "src/objects/api-callbacks.h"
     20 #include "src/snapshot/snapshot.h"
     21 
     22 namespace v8 {
     23 namespace internal {
     24 
     25 MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate,
     26                                           Handle<String> source,
     27                                           bool throw_on_side_effect) {
     28   // Disable breaks in side-effect free mode.
     29   DisableBreak disable_break_scope(isolate->debug(), throw_on_side_effect);
     30 
     31   Handle<Context> context = isolate->native_context();
     32   ScriptOriginOptions origin_options(false, true);
     33   MaybeHandle<SharedFunctionInfo> maybe_function_info =
     34       Compiler::GetSharedFunctionInfoForScript(
     35           isolate, source,
     36           Compiler::ScriptDetails(isolate->factory()->empty_string()),
     37           origin_options, nullptr, nullptr, ScriptCompiler::kNoCompileOptions,
     38           ScriptCompiler::kNoCacheNoReason, NOT_NATIVES_CODE);
     39 
     40   Handle<SharedFunctionInfo> shared_info;
     41   if (!maybe_function_info.ToHandle(&shared_info)) return MaybeHandle<Object>();
     42 
     43   Handle<JSFunction> fun =
     44       isolate->factory()->NewFunctionFromSharedFunctionInfo(shared_info,
     45                                                             context);
     46   if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode();
     47   MaybeHandle<Object> result = Execution::Call(
     48       isolate, fun, Handle<JSObject>(context->global_proxy(), isolate), 0,
     49       nullptr);
     50   if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode();
     51   return result;
     52 }
     53 
     54 MaybeHandle<Object> DebugEvaluate::Local(Isolate* isolate,
     55                                          StackFrame::Id frame_id,
     56                                          int inlined_jsframe_index,
     57                                          Handle<String> source,
     58                                          bool throw_on_side_effect) {
     59   // Handle the processing of break.
     60   DisableBreak disable_break_scope(isolate->debug());
     61 
     62   // Get the frame where the debugging is performed.
     63   StackTraceFrameIterator it(isolate, frame_id);
     64   if (!it.is_javascript()) return isolate->factory()->undefined_value();
     65   JavaScriptFrame* frame = it.javascript_frame();
     66 
     67   // This is not a lot different than DebugEvaluate::Global, except that
     68   // variables accessible by the function we are evaluating from are
     69   // materialized and included on top of the native context. Changes to
     70   // the materialized object are written back afterwards.
     71   // Note that the native context is taken from the original context chain,
     72   // which may not be the current native context of the isolate.
     73   ContextBuilder context_builder(isolate, frame, inlined_jsframe_index);
     74   if (isolate->has_pending_exception()) return MaybeHandle<Object>();
     75 
     76   Handle<Context> context = context_builder.evaluation_context();
     77   Handle<JSObject> receiver(context->global_proxy(), isolate);
     78   MaybeHandle<Object> maybe_result =
     79       Evaluate(isolate, context_builder.outer_info(), context, receiver, source,
     80                throw_on_side_effect);
     81   if (!maybe_result.is_null()) context_builder.UpdateValues();
     82   return maybe_result;
     83 }
     84 
     85 MaybeHandle<Object> DebugEvaluate::WithTopmostArguments(Isolate* isolate,
     86                                                         Handle<String> source) {
     87   // Handle the processing of break.
     88   DisableBreak disable_break_scope(isolate->debug());
     89   Factory* factory = isolate->factory();
     90   JavaScriptFrameIterator it(isolate);
     91 
     92   // Get context and receiver.
     93   Handle<Context> native_context(
     94       Context::cast(it.frame()->context())->native_context(), isolate);
     95 
     96   // Materialize arguments as property on an extension object.
     97   Handle<JSObject> materialized = factory->NewJSObjectWithNullProto();
     98   Handle<String> arguments_str = factory->arguments_string();
     99   JSObject::SetOwnPropertyIgnoreAttributes(
    100       materialized, arguments_str,
    101       Accessors::FunctionGetArguments(it.frame(), 0), NONE)
    102       .Check();
    103 
    104   // Materialize receiver.
    105   Handle<String> this_str = factory->this_string();
    106   JSObject::SetOwnPropertyIgnoreAttributes(
    107       materialized, this_str, Handle<Object>(it.frame()->receiver(), isolate),
    108       NONE)
    109       .Check();
    110 
    111   // Use extension object in a debug-evaluate scope.
    112   Handle<ScopeInfo> scope_info =
    113       ScopeInfo::CreateForWithScope(isolate, Handle<ScopeInfo>::null());
    114   scope_info->SetIsDebugEvaluateScope();
    115   Handle<Context> evaluation_context =
    116       factory->NewDebugEvaluateContext(native_context, scope_info, materialized,
    117                                        Handle<Context>(), Handle<StringSet>());
    118   Handle<SharedFunctionInfo> outer_info(
    119       native_context->empty_function()->shared(), isolate);
    120   Handle<JSObject> receiver(native_context->global_proxy(), isolate);
    121   const bool throw_on_side_effect = false;
    122   MaybeHandle<Object> maybe_result =
    123       Evaluate(isolate, outer_info, evaluation_context, receiver, source,
    124                throw_on_side_effect);
    125   return maybe_result;
    126 }
    127 
    128 // Compile and evaluate source for the given context.
    129 MaybeHandle<Object> DebugEvaluate::Evaluate(
    130     Isolate* isolate, Handle<SharedFunctionInfo> outer_info,
    131     Handle<Context> context, Handle<Object> receiver, Handle<String> source,
    132     bool throw_on_side_effect) {
    133   Handle<JSFunction> eval_fun;
    134   ASSIGN_RETURN_ON_EXCEPTION(
    135       isolate, eval_fun,
    136       Compiler::GetFunctionFromEval(source, outer_info, context,
    137                                     LanguageMode::kSloppy, NO_PARSE_RESTRICTION,
    138                                     kNoSourcePosition, kNoSourcePosition,
    139                                     kNoSourcePosition),
    140       Object);
    141 
    142   Handle<Object> result;
    143   bool sucess = false;
    144   if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode();
    145   sucess = Execution::Call(isolate, eval_fun, receiver, 0, nullptr)
    146                .ToHandle(&result);
    147   if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode();
    148   if (!sucess) {
    149     DCHECK(isolate->has_pending_exception());
    150     return MaybeHandle<Object>();
    151   }
    152 
    153   // Skip the global proxy as it has no properties and always delegates to the
    154   // real global object.
    155   if (result->IsJSGlobalProxy()) {
    156     PrototypeIterator iter(isolate, Handle<JSGlobalProxy>::cast(result));
    157     // TODO(verwaest): This will crash when the global proxy is detached.
    158     result = PrototypeIterator::GetCurrent<JSObject>(iter);
    159   }
    160 
    161   return result;
    162 }
    163 
    164 Handle<SharedFunctionInfo> DebugEvaluate::ContextBuilder::outer_info() const {
    165   return handle(frame_inspector_.GetFunction()->shared(), isolate_);
    166 }
    167 
    168 DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
    169                                               JavaScriptFrame* frame,
    170                                               int inlined_jsframe_index)
    171     : isolate_(isolate),
    172       frame_inspector_(frame, inlined_jsframe_index, isolate),
    173       scope_iterator_(isolate, &frame_inspector_,
    174                       ScopeIterator::COLLECT_NON_LOCALS) {
    175   Handle<Context> outer_context(frame_inspector_.GetFunction()->context(),
    176                                 isolate);
    177   evaluation_context_ = outer_context;
    178   Factory* factory = isolate->factory();
    179 
    180   if (scope_iterator_.Done()) return;
    181 
    182   // To evaluate as if we were running eval at the point of the debug break,
    183   // we reconstruct the context chain as follows:
    184   //  - To make stack-allocated variables visible, we materialize them and
    185   //    use a debug-evaluate context to wrap both the materialized object and
    186   //    the original context.
    187   //  - We use the original context chain from the function context to the
    188   //    native context.
    189   //  - Between the function scope and the native context, we only resolve
    190   //    variable names that the current function already uses. Only for these
    191   //    names we can be sure that they will be correctly resolved. For the
    192   //    rest, we only resolve to with, script, and native contexts. We use a
    193   //    whitelist to implement that.
    194   // Context::Lookup has special handling for debug-evaluate contexts:
    195   //  - Look up in the materialized stack variables.
    196   //  - Look up in the original context.
    197   //  - Check the whitelist to find out whether to skip contexts during lookup.
    198   for (; scope_iterator_.InInnerScope(); scope_iterator_.Next()) {
    199     ScopeIterator::ScopeType scope_type = scope_iterator_.Type();
    200     if (scope_type == ScopeIterator::ScopeTypeScript) break;
    201     ContextChainElement context_chain_element;
    202     if (scope_type == ScopeIterator::ScopeTypeLocal ||
    203         scope_iterator_.DeclaresLocals(ScopeIterator::Mode::STACK)) {
    204       context_chain_element.materialized_object =
    205           scope_iterator_.ScopeObject(ScopeIterator::Mode::STACK);
    206     }
    207     if (scope_iterator_.HasContext()) {
    208       context_chain_element.wrapped_context = scope_iterator_.CurrentContext();
    209     }
    210     if (scope_type == ScopeIterator::ScopeTypeLocal) {
    211       context_chain_element.whitelist = scope_iterator_.GetNonLocals();
    212     }
    213     context_chain_.push_back(context_chain_element);
    214   }
    215 
    216   Handle<ScopeInfo> scope_info =
    217       evaluation_context_->IsNativeContext()
    218           ? Handle<ScopeInfo>::null()
    219           : handle(evaluation_context_->scope_info(), isolate);
    220   for (auto rit = context_chain_.rbegin(); rit != context_chain_.rend();
    221        rit++) {
    222     ContextChainElement element = *rit;
    223     scope_info = ScopeInfo::CreateForWithScope(isolate, scope_info);
    224     scope_info->SetIsDebugEvaluateScope();
    225     evaluation_context_ = factory->NewDebugEvaluateContext(
    226         evaluation_context_, scope_info, element.materialized_object,
    227         element.wrapped_context, element.whitelist);
    228   }
    229 }
    230 
    231 
    232 void DebugEvaluate::ContextBuilder::UpdateValues() {
    233   scope_iterator_.Restart();
    234   for (ContextChainElement& element : context_chain_) {
    235     if (!element.materialized_object.is_null()) {
    236       Handle<FixedArray> keys =
    237           KeyAccumulator::GetKeys(element.materialized_object,
    238                                   KeyCollectionMode::kOwnOnly,
    239                                   ENUMERABLE_STRINGS)
    240               .ToHandleChecked();
    241 
    242       for (int i = 0; i < keys->length(); i++) {
    243         DCHECK(keys->get(i)->IsString());
    244         Handle<String> key(String::cast(keys->get(i)), isolate_);
    245         Handle<Object> value =
    246             JSReceiver::GetDataProperty(element.materialized_object, key);
    247         scope_iterator_.SetVariableValue(key, value);
    248       }
    249     }
    250     scope_iterator_.Next();
    251   }
    252 }
    253 
    254 namespace {
    255 
    256 bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
    257 // Use macro to include both inlined and non-inlined version of an intrinsic.
    258 #define INTRINSIC_WHITELIST(V)                \
    259   /* Conversions */                           \
    260   V(NumberToString)                           \
    261   V(ToBigInt)                                 \
    262   V(ToInteger)                                \
    263   V(ToLength)                                 \
    264   V(ToNumber)                                 \
    265   V(ToObject)                                 \
    266   V(ToString)                                 \
    267   /* Type checks */                           \
    268   V(IsArray)                                  \
    269   V(IsDate)                                   \
    270   V(IsFunction)                               \
    271   V(IsJSProxy)                                \
    272   V(IsJSReceiver)                             \
    273   V(IsRegExp)                                 \
    274   V(IsSmi)                                    \
    275   V(IsTypedArray)                             \
    276   /* Loads */                                 \
    277   V(LoadLookupSlotForCall)                    \
    278   V(GetProperty)                              \
    279   /* Arrays */                                \
    280   V(ArraySpeciesConstructor)                  \
    281   V(EstimateNumberOfElements)                 \
    282   V(GetArrayKeys)                             \
    283   V(HasComplexElements)                       \
    284   V(HasFastPackedElements)                    \
    285   V(NewArray)                                 \
    286   V(NormalizeElements)                        \
    287   V(PrepareElementsForSort)                   \
    288   V(TrySliceSimpleNonFastElements)            \
    289   V(TypedArrayGetBuffer)                      \
    290   /* Errors */                                \
    291   V(NewTypeError)                             \
    292   V(ReThrow)                                  \
    293   V(ThrowCalledNonCallable)                   \
    294   V(ThrowInvalidStringLength)                 \
    295   V(ThrowIteratorResultNotAnObject)           \
    296   V(ThrowReferenceError)                      \
    297   V(ThrowSymbolIteratorInvalid)               \
    298   /* Strings */                               \
    299   V(RegExpInternalReplace)                    \
    300   V(StringIncludes)                           \
    301   V(StringIndexOf)                            \
    302   V(StringReplaceOneCharWithString)           \
    303   V(StringSubstring)                          \
    304   V(StringToNumber)                           \
    305   V(StringTrim)                               \
    306   /* BigInts */                               \
    307   V(BigIntEqualToBigInt)                      \
    308   V(BigIntToBoolean)                          \
    309   V(BigIntToNumber)                           \
    310   /* Literals */                              \
    311   V(CreateArrayLiteral)                       \
    312   V(CreateArrayLiteralWithoutAllocationSite)  \
    313   V(CreateObjectLiteral)                      \
    314   V(CreateObjectLiteralWithoutAllocationSite) \
    315   V(CreateRegExpLiteral)                      \
    316   /* Called from builtins */                  \
    317   V(AllocateInNewSpace)                       \
    318   V(AllocateInTargetSpace)                    \
    319   V(AllocateSeqOneByteString)                 \
    320   V(AllocateSeqTwoByteString)                 \
    321   V(ArrayIncludes_Slow)                       \
    322   V(ArrayIndexOf)                             \
    323   V(ArrayIsArray)                             \
    324   V(ClassOf)                                  \
    325   V(GenerateRandomNumbers)                    \
    326   V(GetFunctionName)                          \
    327   V(GetOwnPropertyDescriptor)                 \
    328   V(GlobalPrint)                              \
    329   V(HasProperty)                              \
    330   V(ObjectCreate)                             \
    331   V(ObjectEntries)                            \
    332   V(ObjectEntriesSkipFastPath)                \
    333   V(ObjectHasOwnProperty)                     \
    334   V(ObjectValues)                             \
    335   V(ObjectValuesSkipFastPath)                 \
    336   V(ObjectGetOwnPropertyNames)                \
    337   V(ObjectGetOwnPropertyNamesTryFast)         \
    338   V(RegExpInitializeAndCompile)               \
    339   V(StackGuard)                               \
    340   V(StringAdd)                                \
    341   V(StringCharCodeAt)                         \
    342   V(StringEqual)                              \
    343   V(StringIndexOfUnchecked)                   \
    344   V(StringParseFloat)                         \
    345   V(StringParseInt)                           \
    346   V(SymbolDescriptiveString)                  \
    347   V(ThrowRangeError)                          \
    348   V(ThrowTypeError)                           \
    349   V(ToName)                                   \
    350   V(TransitionElementsKind)                   \
    351   /* Misc. */                                 \
    352   V(Call)                                     \
    353   V(CompleteInobjectSlackTrackingForMap)      \
    354   V(HasInPrototypeChain)                      \
    355   V(MaxSmi)                                   \
    356   V(NewObject)                                \
    357   V(SmiLexicographicCompare)                  \
    358   V(StringMaxLength)                          \
    359   V(StringToArray)                            \
    360   /* Test */                                  \
    361   V(GetOptimizationStatus)                    \
    362   V(OptimizeFunctionOnNextCall)               \
    363   V(OptimizeOsr)                              \
    364   V(UnblockConcurrentRecompilation)
    365 
    366 #define CASE(Name)       \
    367   case Runtime::k##Name: \
    368   case Runtime::kInline##Name:
    369 
    370   switch (id) {
    371     INTRINSIC_WHITELIST(CASE)
    372     return true;
    373     default:
    374       if (FLAG_trace_side_effect_free_debug_evaluate) {
    375         PrintF("[debug-evaluate] intrinsic %s may cause side effect.\n",
    376                Runtime::FunctionForId(id)->name);
    377       }
    378       return false;
    379   }
    380 
    381 #undef CASE
    382 #undef INTRINSIC_WHITELIST
    383 }
    384 
    385 #ifdef DEBUG
    386 bool BuiltinToIntrinsicHasNoSideEffect(Builtins::Name builtin_id,
    387                                        Runtime::FunctionId intrinsic_id) {
    388   // First check the intrinsic whitelist.
    389   if (IntrinsicHasNoSideEffect(intrinsic_id)) return true;
    390 
    391 // Whitelist intrinsics called from specific builtins.
    392 #define BUILTIN_INTRINSIC_WHITELIST(V, W)                                 \
    393   /* Arrays */                                                            \
    394   V(Builtins::kArrayFilter, W(CreateDataProperty))                        \
    395   V(Builtins::kArrayMap, W(CreateDataProperty))                           \
    396   V(Builtins::kArrayPrototypeSlice, W(CreateDataProperty) W(SetProperty)) \
    397   /* TypedArrays */                                                       \
    398   V(Builtins::kTypedArrayConstructor,                                     \
    399     W(TypedArrayCopyElements) W(ThrowInvalidTypedArrayAlignment))         \
    400   V(Builtins::kTypedArrayPrototypeFilter, W(TypedArrayCopyElements))      \
    401   V(Builtins::kTypedArrayPrototypeMap, W(SetProperty))
    402 
    403 #define CASE(Builtin, ...) \
    404   case Builtin:            \
    405     return (__VA_ARGS__ false);
    406 
    407 #define MATCH(Intrinsic)                   \
    408   intrinsic_id == Runtime::k##Intrinsic || \
    409       intrinsic_id == Runtime::kInline##Intrinsic ||
    410 
    411   switch (builtin_id) {
    412     BUILTIN_INTRINSIC_WHITELIST(CASE, MATCH)
    413     default:
    414       return false;
    415   }
    416 
    417 #undef MATCH
    418 #undef CASE
    419 #undef BUILTIN_INTRINSIC_WHITELIST
    420 }
    421 #endif  // DEBUG
    422 
    423 bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
    424   typedef interpreter::Bytecode Bytecode;
    425   typedef interpreter::Bytecodes Bytecodes;
    426   if (Bytecodes::IsWithoutExternalSideEffects(bytecode)) return true;
    427   if (Bytecodes::IsCallOrConstruct(bytecode)) return true;
    428   if (Bytecodes::IsJumpIfToBoolean(bytecode)) return true;
    429   if (Bytecodes::IsPrefixScalingBytecode(bytecode)) return true;
    430   switch (bytecode) {
    431     // Whitelist for bytecodes.
    432     // Loads.
    433     case Bytecode::kLdaLookupSlot:
    434     case Bytecode::kLdaGlobal:
    435     case Bytecode::kLdaNamedProperty:
    436     case Bytecode::kLdaKeyedProperty:
    437     case Bytecode::kLdaGlobalInsideTypeof:
    438     case Bytecode::kLdaLookupSlotInsideTypeof:
    439     // Arithmetics.
    440     case Bytecode::kAdd:
    441     case Bytecode::kAddSmi:
    442     case Bytecode::kSub:
    443     case Bytecode::kSubSmi:
    444     case Bytecode::kMul:
    445     case Bytecode::kMulSmi:
    446     case Bytecode::kDiv:
    447     case Bytecode::kDivSmi:
    448     case Bytecode::kMod:
    449     case Bytecode::kModSmi:
    450     case Bytecode::kExp:
    451     case Bytecode::kExpSmi:
    452     case Bytecode::kNegate:
    453     case Bytecode::kBitwiseAnd:
    454     case Bytecode::kBitwiseAndSmi:
    455     case Bytecode::kBitwiseNot:
    456     case Bytecode::kBitwiseOr:
    457     case Bytecode::kBitwiseOrSmi:
    458     case Bytecode::kBitwiseXor:
    459     case Bytecode::kBitwiseXorSmi:
    460     case Bytecode::kShiftLeft:
    461     case Bytecode::kShiftLeftSmi:
    462     case Bytecode::kShiftRight:
    463     case Bytecode::kShiftRightSmi:
    464     case Bytecode::kShiftRightLogical:
    465     case Bytecode::kShiftRightLogicalSmi:
    466     case Bytecode::kInc:
    467     case Bytecode::kDec:
    468     case Bytecode::kLogicalNot:
    469     case Bytecode::kToBooleanLogicalNot:
    470     case Bytecode::kTypeOf:
    471     // Contexts.
    472     case Bytecode::kCreateBlockContext:
    473     case Bytecode::kCreateCatchContext:
    474     case Bytecode::kCreateFunctionContext:
    475     case Bytecode::kCreateEvalContext:
    476     case Bytecode::kCreateWithContext:
    477     // Literals.
    478     case Bytecode::kCreateArrayLiteral:
    479     case Bytecode::kCreateEmptyArrayLiteral:
    480     case Bytecode::kCreateObjectLiteral:
    481     case Bytecode::kCreateEmptyObjectLiteral:
    482     case Bytecode::kCreateRegExpLiteral:
    483     // Allocations.
    484     case Bytecode::kCreateClosure:
    485     case Bytecode::kCreateUnmappedArguments:
    486     case Bytecode::kCreateRestParameter:
    487     // Comparisons.
    488     case Bytecode::kTestEqual:
    489     case Bytecode::kTestEqualStrict:
    490     case Bytecode::kTestLessThan:
    491     case Bytecode::kTestLessThanOrEqual:
    492     case Bytecode::kTestGreaterThan:
    493     case Bytecode::kTestGreaterThanOrEqual:
    494     case Bytecode::kTestInstanceOf:
    495     case Bytecode::kTestIn:
    496     case Bytecode::kTestReferenceEqual:
    497     case Bytecode::kTestUndetectable:
    498     case Bytecode::kTestTypeOf:
    499     case Bytecode::kTestUndefined:
    500     case Bytecode::kTestNull:
    501     // Conversions.
    502     case Bytecode::kToObject:
    503     case Bytecode::kToName:
    504     case Bytecode::kToNumber:
    505     case Bytecode::kToNumeric:
    506     case Bytecode::kToString:
    507     // Misc.
    508     case Bytecode::kForInEnumerate:
    509     case Bytecode::kForInPrepare:
    510     case Bytecode::kForInContinue:
    511     case Bytecode::kForInNext:
    512     case Bytecode::kForInStep:
    513     case Bytecode::kThrow:
    514     case Bytecode::kReThrow:
    515     case Bytecode::kThrowReferenceErrorIfHole:
    516     case Bytecode::kThrowSuperNotCalledIfHole:
    517     case Bytecode::kThrowSuperAlreadyCalledIfNotHole:
    518     case Bytecode::kIllegal:
    519     case Bytecode::kCallJSRuntime:
    520     case Bytecode::kStackCheck:
    521     case Bytecode::kReturn:
    522     case Bytecode::kSetPendingMessage:
    523       return true;
    524     default:
    525       return false;
    526   }
    527 }
    528 
    529 DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) {
    530   switch (id) {
    531     // Whitelist for builtins.
    532     // Object builtins.
    533     case Builtins::kObjectConstructor:
    534     case Builtins::kObjectCreate:
    535     case Builtins::kObjectEntries:
    536     case Builtins::kObjectGetOwnPropertyDescriptor:
    537     case Builtins::kObjectGetOwnPropertyDescriptors:
    538     case Builtins::kObjectGetOwnPropertyNames:
    539     case Builtins::kObjectGetOwnPropertySymbols:
    540     case Builtins::kObjectGetPrototypeOf:
    541     case Builtins::kObjectIs:
    542     case Builtins::kObjectIsExtensible:
    543     case Builtins::kObjectIsFrozen:
    544     case Builtins::kObjectIsSealed:
    545     case Builtins::kObjectPrototypeValueOf:
    546     case Builtins::kObjectValues:
    547     case Builtins::kObjectPrototypeHasOwnProperty:
    548     case Builtins::kObjectPrototypeIsPrototypeOf:
    549     case Builtins::kObjectPrototypePropertyIsEnumerable:
    550     case Builtins::kObjectPrototypeToString:
    551     // Array builtins.
    552     case Builtins::kArrayIsArray:
    553     case Builtins::kArrayConstructor:
    554     case Builtins::kArrayIndexOf:
    555     case Builtins::kArrayPrototypeValues:
    556     case Builtins::kArrayIncludes:
    557     case Builtins::kArrayPrototypeEntries:
    558     case Builtins::kArrayPrototypeFill:
    559     case Builtins::kArrayPrototypeFind:
    560     case Builtins::kArrayPrototypeFindIndex:
    561     case Builtins::kArrayPrototypeFlat:
    562     case Builtins::kArrayPrototypeFlatMap:
    563     case Builtins::kArrayPrototypeKeys:
    564     case Builtins::kArrayPrototypeSlice:
    565     case Builtins::kArrayPrototypeSort:
    566     case Builtins::kArrayForEach:
    567     case Builtins::kArrayEvery:
    568     case Builtins::kArraySome:
    569     case Builtins::kArrayConcat:
    570     case Builtins::kArrayFilter:
    571     case Builtins::kArrayMap:
    572     case Builtins::kArrayReduce:
    573     case Builtins::kArrayReduceRight:
    574     // Trace builtins.
    575     case Builtins::kIsTraceCategoryEnabled:
    576     case Builtins::kTrace:
    577     // TypedArray builtins.
    578     case Builtins::kTypedArrayConstructor:
    579     case Builtins::kTypedArrayPrototypeBuffer:
    580     case Builtins::kTypedArrayPrototypeByteLength:
    581     case Builtins::kTypedArrayPrototypeByteOffset:
    582     case Builtins::kTypedArrayPrototypeLength:
    583     case Builtins::kTypedArrayPrototypeEntries:
    584     case Builtins::kTypedArrayPrototypeKeys:
    585     case Builtins::kTypedArrayPrototypeValues:
    586     case Builtins::kTypedArrayPrototypeFind:
    587     case Builtins::kTypedArrayPrototypeFindIndex:
    588     case Builtins::kTypedArrayPrototypeIncludes:
    589     case Builtins::kTypedArrayPrototypeIndexOf:
    590     case Builtins::kTypedArrayPrototypeLastIndexOf:
    591     case Builtins::kTypedArrayPrototypeSlice:
    592     case Builtins::kTypedArrayPrototypeSubArray:
    593     case Builtins::kTypedArrayPrototypeEvery:
    594     case Builtins::kTypedArrayPrototypeSome:
    595     case Builtins::kTypedArrayPrototypeFilter:
    596     case Builtins::kTypedArrayPrototypeMap:
    597     case Builtins::kTypedArrayPrototypeReduce:
    598     case Builtins::kTypedArrayPrototypeReduceRight:
    599     case Builtins::kTypedArrayPrototypeForEach:
    600     // ArrayBuffer builtins.
    601     case Builtins::kArrayBufferConstructor:
    602     case Builtins::kArrayBufferPrototypeGetByteLength:
    603     case Builtins::kArrayBufferIsView:
    604     case Builtins::kArrayBufferPrototypeSlice:
    605     case Builtins::kReturnReceiver:
    606     // DataView builtins.
    607     case Builtins::kDataViewConstructor:
    608     case Builtins::kDataViewPrototypeGetBuffer:
    609     case Builtins::kDataViewPrototypeGetByteLength:
    610     case Builtins::kDataViewPrototypeGetByteOffset:
    611     case Builtins::kDataViewPrototypeGetInt8:
    612     case Builtins::kDataViewPrototypeGetUint8:
    613     case Builtins::kDataViewPrototypeGetInt16:
    614     case Builtins::kDataViewPrototypeGetUint16:
    615     case Builtins::kDataViewPrototypeGetInt32:
    616     case Builtins::kDataViewPrototypeGetUint32:
    617     case Builtins::kDataViewPrototypeGetFloat32:
    618     case Builtins::kDataViewPrototypeGetFloat64:
    619     case Builtins::kDataViewPrototypeGetBigInt64:
    620     case Builtins::kDataViewPrototypeGetBigUint64:
    621     // Boolean bulitins.
    622     case Builtins::kBooleanConstructor:
    623     case Builtins::kBooleanPrototypeToString:
    624     case Builtins::kBooleanPrototypeValueOf:
    625     // Date builtins.
    626     case Builtins::kDateConstructor:
    627     case Builtins::kDateNow:
    628     case Builtins::kDateParse:
    629     case Builtins::kDatePrototypeGetDate:
    630     case Builtins::kDatePrototypeGetDay:
    631     case Builtins::kDatePrototypeGetFullYear:
    632     case Builtins::kDatePrototypeGetHours:
    633     case Builtins::kDatePrototypeGetMilliseconds:
    634     case Builtins::kDatePrototypeGetMinutes:
    635     case Builtins::kDatePrototypeGetMonth:
    636     case Builtins::kDatePrototypeGetSeconds:
    637     case Builtins::kDatePrototypeGetTime:
    638     case Builtins::kDatePrototypeGetTimezoneOffset:
    639     case Builtins::kDatePrototypeGetUTCDate:
    640     case Builtins::kDatePrototypeGetUTCDay:
    641     case Builtins::kDatePrototypeGetUTCFullYear:
    642     case Builtins::kDatePrototypeGetUTCHours:
    643     case Builtins::kDatePrototypeGetUTCMilliseconds:
    644     case Builtins::kDatePrototypeGetUTCMinutes:
    645     case Builtins::kDatePrototypeGetUTCMonth:
    646     case Builtins::kDatePrototypeGetUTCSeconds:
    647     case Builtins::kDatePrototypeGetYear:
    648     case Builtins::kDatePrototypeToDateString:
    649     case Builtins::kDatePrototypeToISOString:
    650     case Builtins::kDatePrototypeToUTCString:
    651     case Builtins::kDatePrototypeToString:
    652     case Builtins::kDatePrototypeToTimeString:
    653     case Builtins::kDatePrototypeToJson:
    654     case Builtins::kDatePrototypeToPrimitive:
    655     case Builtins::kDatePrototypeValueOf:
    656     // Map builtins.
    657     case Builtins::kMapConstructor:
    658     case Builtins::kMapPrototypeForEach:
    659     case Builtins::kMapPrototypeGet:
    660     case Builtins::kMapPrototypeHas:
    661     case Builtins::kMapPrototypeEntries:
    662     case Builtins::kMapPrototypeGetSize:
    663     case Builtins::kMapPrototypeKeys:
    664     case Builtins::kMapPrototypeValues:
    665     // WeakMap builtins.
    666     case Builtins::kWeakMapConstructor:
    667     case Builtins::kWeakMapGet:
    668     case Builtins::kWeakMapHas:
    669     // Math builtins.
    670     case Builtins::kMathAbs:
    671     case Builtins::kMathAcos:
    672     case Builtins::kMathAcosh:
    673     case Builtins::kMathAsin:
    674     case Builtins::kMathAsinh:
    675     case Builtins::kMathAtan:
    676     case Builtins::kMathAtanh:
    677     case Builtins::kMathAtan2:
    678     case Builtins::kMathCeil:
    679     case Builtins::kMathCbrt:
    680     case Builtins::kMathExpm1:
    681     case Builtins::kMathClz32:
    682     case Builtins::kMathCos:
    683     case Builtins::kMathCosh:
    684     case Builtins::kMathExp:
    685     case Builtins::kMathFloor:
    686     case Builtins::kMathFround:
    687     case Builtins::kMathHypot:
    688     case Builtins::kMathImul:
    689     case Builtins::kMathLog:
    690     case Builtins::kMathLog1p:
    691     case Builtins::kMathLog2:
    692     case Builtins::kMathLog10:
    693     case Builtins::kMathMax:
    694     case Builtins::kMathMin:
    695     case Builtins::kMathPow:
    696     case Builtins::kMathRandom:
    697     case Builtins::kMathRound:
    698     case Builtins::kMathSign:
    699     case Builtins::kMathSin:
    700     case Builtins::kMathSinh:
    701     case Builtins::kMathSqrt:
    702     case Builtins::kMathTan:
    703     case Builtins::kMathTanh:
    704     case Builtins::kMathTrunc:
    705     // Number builtins.
    706     case Builtins::kNumberConstructor:
    707     case Builtins::kNumberIsFinite:
    708     case Builtins::kNumberIsInteger:
    709     case Builtins::kNumberIsNaN:
    710     case Builtins::kNumberIsSafeInteger:
    711     case Builtins::kNumberParseFloat:
    712     case Builtins::kNumberParseInt:
    713     case Builtins::kNumberPrototypeToExponential:
    714     case Builtins::kNumberPrototypeToFixed:
    715     case Builtins::kNumberPrototypeToPrecision:
    716     case Builtins::kNumberPrototypeToString:
    717     case Builtins::kNumberPrototypeValueOf:
    718     // BigInt builtins.
    719     case Builtins::kBigIntConstructor:
    720     case Builtins::kBigIntAsIntN:
    721     case Builtins::kBigIntAsUintN:
    722     case Builtins::kBigIntPrototypeToString:
    723     case Builtins::kBigIntPrototypeValueOf:
    724     // Set builtins.
    725     case Builtins::kSetConstructor:
    726     case Builtins::kSetPrototypeEntries:
    727     case Builtins::kSetPrototypeForEach:
    728     case Builtins::kSetPrototypeGetSize:
    729     case Builtins::kSetPrototypeHas:
    730     case Builtins::kSetPrototypeValues:
    731     // WeakSet builtins.
    732     case Builtins::kWeakSetConstructor:
    733     case Builtins::kWeakSetHas:
    734     // String builtins. Strings are immutable.
    735     case Builtins::kStringFromCharCode:
    736     case Builtins::kStringFromCodePoint:
    737     case Builtins::kStringConstructor:
    738     case Builtins::kStringPrototypeAnchor:
    739     case Builtins::kStringPrototypeBig:
    740     case Builtins::kStringPrototypeBlink:
    741     case Builtins::kStringPrototypeBold:
    742     case Builtins::kStringPrototypeCharAt:
    743     case Builtins::kStringPrototypeCharCodeAt:
    744     case Builtins::kStringPrototypeCodePointAt:
    745     case Builtins::kStringPrototypeConcat:
    746     case Builtins::kStringPrototypeEndsWith:
    747     case Builtins::kStringPrototypeFixed:
    748     case Builtins::kStringPrototypeFontcolor:
    749     case Builtins::kStringPrototypeFontsize:
    750     case Builtins::kStringPrototypeIncludes:
    751     case Builtins::kStringPrototypeIndexOf:
    752     case Builtins::kStringPrototypeItalics:
    753     case Builtins::kStringPrototypeLastIndexOf:
    754     case Builtins::kStringPrototypeLink:
    755     case Builtins::kStringPrototypePadEnd:
    756     case Builtins::kStringPrototypePadStart:
    757     case Builtins::kStringPrototypeRepeat:
    758     case Builtins::kStringPrototypeSlice:
    759     case Builtins::kStringPrototypeSmall:
    760     case Builtins::kStringPrototypeStartsWith:
    761     case Builtins::kStringPrototypeStrike:
    762     case Builtins::kStringPrototypeSub:
    763     case Builtins::kStringPrototypeSubstr:
    764     case Builtins::kStringPrototypeSubstring:
    765     case Builtins::kStringPrototypeSup:
    766     case Builtins::kStringPrototypeToString:
    767 #ifndef V8_INTL_SUPPORT
    768     case Builtins::kStringPrototypeToLowerCase:
    769     case Builtins::kStringPrototypeToUpperCase:
    770 #endif
    771     case Builtins::kStringPrototypeTrim:
    772     case Builtins::kStringPrototypeTrimEnd:
    773     case Builtins::kStringPrototypeTrimStart:
    774     case Builtins::kStringPrototypeValueOf:
    775     case Builtins::kStringToNumber:
    776     case Builtins::kStringSubstring:
    777     // Symbol builtins.
    778     case Builtins::kSymbolConstructor:
    779     case Builtins::kSymbolKeyFor:
    780     case Builtins::kSymbolPrototypeToString:
    781     case Builtins::kSymbolPrototypeValueOf:
    782     case Builtins::kSymbolPrototypeToPrimitive:
    783     // JSON builtins.
    784     case Builtins::kJsonParse:
    785     case Builtins::kJsonStringify:
    786     // Global function builtins.
    787     case Builtins::kGlobalDecodeURI:
    788     case Builtins::kGlobalDecodeURIComponent:
    789     case Builtins::kGlobalEncodeURI:
    790     case Builtins::kGlobalEncodeURIComponent:
    791     case Builtins::kGlobalEscape:
    792     case Builtins::kGlobalUnescape:
    793     case Builtins::kGlobalIsFinite:
    794     case Builtins::kGlobalIsNaN:
    795     // Function builtins.
    796     case Builtins::kFunctionPrototypeToString:
    797     case Builtins::kFunctionPrototypeBind:
    798     case Builtins::kFastFunctionPrototypeBind:
    799     case Builtins::kFunctionPrototypeCall:
    800     case Builtins::kFunctionPrototypeApply:
    801     // Error builtins.
    802     case Builtins::kErrorConstructor:
    803     case Builtins::kMakeError:
    804     case Builtins::kMakeTypeError:
    805     case Builtins::kMakeSyntaxError:
    806     case Builtins::kMakeRangeError:
    807     case Builtins::kMakeURIError:
    808     // RegExp builtins.
    809     case Builtins::kRegExpConstructor:
    810       return DebugInfo::kHasNoSideEffect;
    811     // Set builtins.
    812     case Builtins::kSetIteratorPrototypeNext:
    813     case Builtins::kSetPrototypeAdd:
    814     case Builtins::kSetPrototypeClear:
    815     case Builtins::kSetPrototypeDelete:
    816     // Array builtins.
    817     case Builtins::kArrayIteratorPrototypeNext:
    818     case Builtins::kArrayPrototypePop:
    819     case Builtins::kArrayPrototypePush:
    820     case Builtins::kArrayPrototypeReverse:
    821     case Builtins::kArrayPrototypeShift:
    822     case Builtins::kArraySplice:
    823     case Builtins::kArrayUnshift:
    824     // Map builtins.
    825     case Builtins::kMapIteratorPrototypeNext:
    826     case Builtins::kMapPrototypeClear:
    827     case Builtins::kMapPrototypeDelete:
    828     case Builtins::kMapPrototypeSet:
    829     // RegExp builtins.
    830     case Builtins::kRegExpPrototypeTest:
    831     case Builtins::kRegExpPrototypeExec:
    832     case Builtins::kRegExpPrototypeSplit:
    833     case Builtins::kRegExpPrototypeFlagsGetter:
    834     case Builtins::kRegExpPrototypeGlobalGetter:
    835     case Builtins::kRegExpPrototypeIgnoreCaseGetter:
    836     case Builtins::kRegExpPrototypeMultilineGetter:
    837     case Builtins::kRegExpPrototypeDotAllGetter:
    838     case Builtins::kRegExpPrototypeUnicodeGetter:
    839     case Builtins::kRegExpPrototypeStickyGetter:
    840       return DebugInfo::kRequiresRuntimeChecks;
    841     default:
    842       if (FLAG_trace_side_effect_free_debug_evaluate) {
    843         PrintF("[debug-evaluate] built-in %s may cause side effect.\n",
    844                Builtins::name(id));
    845       }
    846       return DebugInfo::kHasSideEffects;
    847   }
    848 }
    849 
    850 bool BytecodeRequiresRuntimeCheck(interpreter::Bytecode bytecode) {
    851   typedef interpreter::Bytecode Bytecode;
    852   switch (bytecode) {
    853     case Bytecode::kStaNamedProperty:
    854     case Bytecode::kStaNamedOwnProperty:
    855     case Bytecode::kStaKeyedProperty:
    856     case Bytecode::kStaInArrayLiteral:
    857     case Bytecode::kStaDataPropertyInLiteral:
    858     case Bytecode::kStaCurrentContextSlot:
    859       return true;
    860     default:
    861       return false;
    862   }
    863 }
    864 
    865 }  // anonymous namespace
    866 
    867 // static
    868 DebugInfo::SideEffectState DebugEvaluate::FunctionGetSideEffectState(
    869     Isolate* isolate, Handle<SharedFunctionInfo> info) {
    870   if (FLAG_trace_side_effect_free_debug_evaluate) {
    871     PrintF("[debug-evaluate] Checking function %s for side effect.\n",
    872            info->DebugName()->ToCString().get());
    873   }
    874 
    875   DCHECK(info->is_compiled());
    876   if (info->HasBytecodeArray()) {
    877     // Check bytecodes against whitelist.
    878     Handle<BytecodeArray> bytecode_array(info->GetBytecodeArray(), isolate);
    879     if (FLAG_trace_side_effect_free_debug_evaluate) {
    880       bytecode_array->Print();
    881     }
    882     bool requires_runtime_checks = false;
    883     for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
    884          it.Advance()) {
    885       interpreter::Bytecode bytecode = it.current_bytecode();
    886 
    887       if (interpreter::Bytecodes::IsCallRuntime(bytecode)) {
    888         Runtime::FunctionId id =
    889             (bytecode == interpreter::Bytecode::kInvokeIntrinsic)
    890                 ? it.GetIntrinsicIdOperand(0)
    891                 : it.GetRuntimeIdOperand(0);
    892         if (IntrinsicHasNoSideEffect(id)) continue;
    893         return DebugInfo::kHasSideEffects;
    894       }
    895 
    896       if (BytecodeHasNoSideEffect(bytecode)) continue;
    897       if (BytecodeRequiresRuntimeCheck(bytecode)) {
    898         requires_runtime_checks = true;
    899         continue;
    900       }
    901 
    902       if (FLAG_trace_side_effect_free_debug_evaluate) {
    903         PrintF("[debug-evaluate] bytecode %s may cause side effect.\n",
    904                interpreter::Bytecodes::ToString(bytecode));
    905       }
    906 
    907       // Did not match whitelist.
    908       return DebugInfo::kHasSideEffects;
    909     }
    910     return requires_runtime_checks ? DebugInfo::kRequiresRuntimeChecks
    911                                    : DebugInfo::kHasNoSideEffect;
    912   } else if (info->IsApiFunction()) {
    913     if (info->GetCode()->is_builtin()) {
    914       return info->GetCode()->builtin_index() == Builtins::kHandleApiCall
    915                  ? DebugInfo::kHasNoSideEffect
    916                  : DebugInfo::kHasSideEffects;
    917     }
    918   } else {
    919     // Check built-ins against whitelist.
    920     int builtin_index =
    921         info->HasBuiltinId() ? info->builtin_id() : Builtins::kNoBuiltinId;
    922     DCHECK_NE(Builtins::kDeserializeLazy, builtin_index);
    923     if (!Builtins::IsBuiltinId(builtin_index))
    924       return DebugInfo::kHasSideEffects;
    925     DebugInfo::SideEffectState state =
    926         BuiltinGetSideEffectState(static_cast<Builtins::Name>(builtin_index));
    927 #ifdef DEBUG
    928     if (state == DebugInfo::kHasNoSideEffect) {
    929       Code* code = isolate->builtins()->builtin(builtin_index);
    930       if (code->builtin_index() == Builtins::kDeserializeLazy) {
    931         // Target builtin is not yet deserialized. Deserialize it now.
    932 
    933         DCHECK(Builtins::IsLazy(builtin_index));
    934         DCHECK_EQ(Builtins::TFJ, Builtins::KindOf(builtin_index));
    935 
    936         code = Snapshot::DeserializeBuiltin(isolate, builtin_index);
    937         DCHECK_NE(Builtins::kDeserializeLazy, code->builtin_index());
    938       }
    939       // TODO(yangguo): Check builtin-to-builtin calls too.
    940       int mode = RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE);
    941       bool failed = false;
    942       for (RelocIterator it(code, mode); !it.done(); it.next()) {
    943         RelocInfo* rinfo = it.rinfo();
    944         Address address = rinfo->target_external_reference();
    945         const Runtime::Function* function = Runtime::FunctionForEntry(address);
    946         if (function == nullptr) continue;
    947         if (!BuiltinToIntrinsicHasNoSideEffect(
    948                 static_cast<Builtins::Name>(builtin_index),
    949                 function->function_id)) {
    950           PrintF("Whitelisted builtin %s calls non-whitelisted intrinsic %s\n",
    951                  Builtins::name(builtin_index), function->name);
    952           failed = true;
    953         }
    954         DCHECK(!failed);
    955       }
    956     }
    957 #endif  // DEBUG
    958     return state;
    959   }
    960 
    961   return DebugInfo::kHasSideEffects;
    962 }
    963 
    964 // static
    965 bool DebugEvaluate::CallbackHasNoSideEffect(Object* callback_info) {
    966   DisallowHeapAllocation no_gc;
    967   if (callback_info->IsAccessorInfo()) {
    968     // List of whitelisted internal accessors can be found in accessors.h.
    969     AccessorInfo* info = AccessorInfo::cast(callback_info);
    970     if (info->has_no_side_effect()) return true;
    971     if (FLAG_trace_side_effect_free_debug_evaluate) {
    972       PrintF("[debug-evaluate] API Callback '");
    973       info->name()->ShortPrint();
    974       PrintF("' may cause side effect.\n");
    975     }
    976   } else if (callback_info->IsInterceptorInfo()) {
    977     InterceptorInfo* info = InterceptorInfo::cast(callback_info);
    978     if (info->has_no_side_effect()) return true;
    979     if (FLAG_trace_side_effect_free_debug_evaluate) {
    980       PrintF("[debug-evaluate] API Interceptor may cause side effect.\n");
    981     }
    982   } else if (callback_info->IsCallHandlerInfo()) {
    983     CallHandlerInfo* info = CallHandlerInfo::cast(callback_info);
    984     if (info->IsSideEffectFreeCallHandlerInfo()) return true;
    985     if (FLAG_trace_side_effect_free_debug_evaluate) {
    986       PrintF("[debug-evaluate] API CallHandlerInfo may cause side effect.\n");
    987     }
    988   }
    989   return false;
    990 }
    991 
    992 // static
    993 void DebugEvaluate::ApplySideEffectChecks(
    994     Handle<BytecodeArray> bytecode_array) {
    995   for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
    996        it.Advance()) {
    997     interpreter::Bytecode bytecode = it.current_bytecode();
    998     if (BytecodeRequiresRuntimeCheck(bytecode)) it.ApplyDebugBreak();
    999   }
   1000 }
   1001 
   1002 }  // namespace internal
   1003 }  // namespace v8
   1004