KnownClass.cpp (3243B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "jit/KnownClass.h" 8 9 #include "jit/MIR-wasm.h" 10 #include "jit/MIR.h" 11 #include "vm/ArrayObject.h" 12 #include "vm/Iteration.h" 13 #include "vm/JSFunction.h" 14 #include "vm/PlainObject.h" // js::PlainObject 15 #include "vm/RegExpObject.h" 16 17 using namespace js; 18 using namespace js::jit; 19 20 KnownClass jit::GetObjectKnownClass(const MDefinition* def) { 21 MOZ_ASSERT(def->type() == MIRType::Object); 22 23 switch (def->op()) { 24 case MDefinition::Opcode::NewArray: 25 case MDefinition::Opcode::NewArrayDynamicLength: 26 case MDefinition::Opcode::NewArrayObject: 27 case MDefinition::Opcode::Rest: 28 case MDefinition::Opcode::ArgumentsSlice: 29 case MDefinition::Opcode::FrameArgumentsSlice: 30 case MDefinition::Opcode::InlineArgumentsSlice: 31 return KnownClass::Array; 32 33 case MDefinition::Opcode::NewObject: 34 case MDefinition::Opcode::NewPlainObject: 35 case MDefinition::Opcode::CreateThis: 36 return KnownClass::PlainObject; 37 38 case MDefinition::Opcode::Lambda: 39 case MDefinition::Opcode::FunctionWithProto: 40 return KnownClass::Function; 41 42 case MDefinition::Opcode::RegExp: 43 return KnownClass::RegExp; 44 45 case MDefinition::Opcode::NewIterator: 46 switch (def->toNewIterator()->type()) { 47 case MNewIterator::ArrayIterator: 48 return KnownClass::ArrayIterator; 49 case MNewIterator::StringIterator: 50 return KnownClass::StringIterator; 51 case MNewIterator::RegExpStringIterator: 52 return KnownClass::RegExpStringIterator; 53 } 54 MOZ_CRASH("unreachable"); 55 56 case MDefinition::Opcode::Phi: { 57 if (def->numOperands() == 0) { 58 return KnownClass::None; 59 } 60 61 MDefinition* op = def->getOperand(0); 62 // Check for Phis to avoid recursion for now. 63 if (op->isPhi()) { 64 return KnownClass::None; 65 } 66 67 KnownClass known = GetObjectKnownClass(op); 68 if (known == KnownClass::None) { 69 return KnownClass::None; 70 } 71 72 for (size_t i = 1; i < def->numOperands(); i++) { 73 op = def->getOperand(i); 74 if (op->isPhi() || GetObjectKnownClass(op) != known) { 75 return KnownClass::None; 76 } 77 } 78 79 return known; 80 } 81 82 default: 83 break; 84 } 85 86 return KnownClass::None; 87 } 88 89 const JSClass* jit::GetObjectKnownJSClass(const MDefinition* def) { 90 switch (GetObjectKnownClass(def)) { 91 case KnownClass::PlainObject: 92 return &PlainObject::class_; 93 case KnownClass::Array: 94 return &ArrayObject::class_; 95 case KnownClass::Function: 96 return &FunctionClass; 97 case KnownClass::RegExp: 98 return &RegExpObject::class_; 99 case KnownClass::ArrayIterator: 100 return &ArrayIteratorObject::class_; 101 case KnownClass::StringIterator: 102 return &StringIteratorObject::class_; 103 case KnownClass::RegExpStringIterator: 104 return &RegExpStringIteratorObject::class_; 105 case KnownClass::None: 106 break; 107 } 108 109 return nullptr; 110 }