}
-void HCallKeyed::InternalSetOperandAt(int index, HValue* value) {
- // The key and all the arguments are stored in the base class's arguments_
- // vector. The context is in the object itself. Ugly.
- if (index <= argument_count()) {
- arguments_[index] = value;
- } else {
- context_ = value;
- }
-}
-
-
-void HCallNamed::InternalSetOperandAt(int index, HValue* value) {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- if (index < argument_count()) {
- arguments_[index] = value;
- } else {
- context_ = value;
- }
-}
-
-
-void HCallFunction::InternalSetOperandAt(int index, HValue* value) {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- if (index < argument_count()) {
- arguments_[index] = value;
- } else {
- context_ = value;
- }
-}
-
-
-void HCallGlobal::InternalSetOperandAt(int index, HValue* value) {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- if (index < argument_count()) {
- arguments_[index] = value;
- } else {
- context_ = value;
- }
-}
-
-
-void HCallNew::InternalSetOperandAt(int index, HValue* value) {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- if (index < argument_count()) {
- arguments_[index] = value;
- } else {
- context_ = value;
- }
-}
-
-
void HStoreKeyedGeneric::InternalSetOperandAt(int index, HValue* value) {
if (index < 3) {
operands_[index] = value;
#endif
-HCall::HCall(int count) : arguments_(Zone::NewArray<HValue*>(count), count) {
- for (int i = 0; i < count; ++i) arguments_[i] = NULL;
- set_representation(Representation::Tagged());
- SetAllSideEffects();
+void HCall::PrintDataTo(StringStream* stream) const {
+ stream->Add("#%d", argument_count());
}
-void HCall::PrintDataTo(StringStream* stream) const {
- stream->Add("(");
- for (int i = 0; i < arguments_.length(); ++i) {
- if (i != 0) stream->Add(", ");
- arguments_.at(i)->PrintNameTo(stream);
+void HUnaryCall::PrintDataTo(StringStream* stream) const {
+ value()->PrintNameTo(stream);
+ stream->Add(" ");
+ HCall::PrintDataTo(stream);
+}
+
+
+void HBinaryCall::PrintDataTo(StringStream* stream) const {
+ first()->PrintNameTo(stream);
+ stream->Add(" ");
+ second()->PrintNameTo(stream);
+ stream->Add(" ");
+ HCall::PrintDataTo(stream);
+}
+
+
+void HCallConstantFunction::PrintDataTo(StringStream* stream) const {
+ if (IsApplyFunction()) {
+ stream->Add("optimized apply ");
+ } else {
+ stream->Add("%o ", function()->shared()->DebugName());
}
- stream->Add(")");
+ HCall::PrintDataTo(stream);
+}
+
+
+void HCallNamed::PrintDataTo(StringStream* stream) const {
+ stream->Add("%o ", *name());
+ HUnaryCall::PrintDataTo(stream);
+}
+
+
+void HCallGlobal::PrintDataTo(StringStream* stream) const {
+ stream->Add("%o ", *name());
+ HUnaryCall::PrintDataTo(stream);
+}
+
+
+void HCallKnownGlobal::PrintDataTo(StringStream* stream) const {
+ stream->Add("o ", target()->shared()->DebugName());
+ HCall::PrintDataTo(stream);
+}
+
+
+void HCallRuntime::PrintDataTo(StringStream* stream) const {
+ stream->Add("%o ", *name());
+ HCall::PrintDataTo(stream);
}
void HClassOfTest::PrintDataTo(StringStream* stream) const {
stream->Add("class_of_test(");
- value()->PrintTo(stream);
+ value()->PrintNameTo(stream);
stream->Add(", \"%o\")", *class_name());
}
}
-void HCall::SetArgumentAt(int index, HPushArgument* push_argument) {
- push_argument->set_argument_index(index);
- SetOperandAt(index, push_argument);
-}
-
-
-void HCallConstantFunction::PrintDataTo(StringStream* stream) const {
- if (IsApplyFunction()) {
- stream->Add("SPECIAL function: apply");
- } else {
- stream->Add("%s", *(function()->shared()->DebugName()->ToCString()));
- }
- HCall::PrintDataTo(stream);
-}
-
-
void HControlInstruction::PrintDataTo(StringStream* stream) const {
if (FirstSuccessor() != NULL) {
int first_id = FirstSuccessor()->block_id();
}
-void HPushArgument::PrintDataTo(StringStream* stream) const {
- HUnaryOperation::PrintDataTo(stream);
- if (argument_index() != -1) {
- stream->Add(" [%d]", argument_index_);
- }
-}
-
-
void HChange::PrintDataTo(StringStream* stream) const {
HUnaryOperation::PrintDataTo(stream);
stream->Add(" %s to %s", from_.Mnemonic(), to_.Mnemonic());
}
-void HCallKeyed::PrintDataTo(StringStream* stream) const {
- stream->Add("[");
- key()->PrintNameTo(stream);
- stream->Add("](");
- for (int i = 1; i < arguments_.length(); ++i) {
- if (i != 1) stream->Add(", ");
- arguments_.at(i)->PrintNameTo(stream);
- }
- stream->Add(")");
-}
-
-
-void HCallNamed::PrintDataTo(StringStream* stream) const {
- SmartPointer<char> name_string = name()->ToCString();
- stream->Add("%s ", *name_string);
- HCall::PrintDataTo(stream);
-}
-
-
-void HCallGlobal::PrintDataTo(StringStream* stream) const {
- SmartPointer<char> name_string = name()->ToCString();
- stream->Add("%s ", *name_string);
- HCall::PrintDataTo(stream);
-}
-
-
-void HCallRuntime::PrintDataTo(StringStream* stream) const {
- SmartPointer<char> name_string = name()->ToCString();
- stream->Add("%s ", *name_string);
- HCall::PrintDataTo(stream);
-}
-
-
void HCallStub::PrintDataTo(StringStream* stream) const {
- HUnaryOperation::PrintDataTo(stream);
- stream->Add(" %s(%d)",
- CodeStub::MajorName(major_key_, false),
- argument_count_);
+ stream->Add("%s ",
+ CodeStub::MajorName(major_key_, false));
+ HUnaryCall::PrintDataTo(stream);
}
#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
V(ArithmeticBinaryOperation) \
+ V(BinaryCall) \
V(BinaryOperation) \
V(BitwiseBinaryOperation) \
V(Call) \
V(Phi) \
V(StoreKeyed) \
V(StoreNamed) \
+ V(UnaryCall) \
V(UnaryControlInstruction) \
V(UnaryOperation) \
HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
class HPushArgument: public HUnaryOperation {
public:
- explicit HPushArgument(HValue* value)
- : HUnaryOperation(value), argument_index_(-1) {
- set_representation(Representation::Tagged());
- }
+ explicit HPushArgument(HValue* value) : HUnaryOperation(value) { }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- virtual void PrintDataTo(StringStream* stream) const;
HValue* argument() const { return OperandAt(0); }
- int argument_index() const { return argument_index_; }
- void set_argument_index(int index) {
- ASSERT(argument_index_ == -1 || index == argument_index_);
- argument_index_ = index;
- }
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
-
- private:
- int argument_index_;
};
class HCall: public HInstruction {
public:
- // Construct a call with uninitialized arguments. The argument count
- // includes the receiver.
- explicit HCall(int count);
+ // The argument count includes the receiver.
+ explicit HCall(int argument_count) : argument_count_(argument_count) {
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
virtual HType CalculateInferredType() const { return HType::Tagged(); }
- // TODO(3190496): This needs a cleanup. We don't want the arguments
- // be operands of the call instruction. This results in bad code quality.
- virtual int argument_count() const { return arguments_.length(); }
- virtual int OperandCount() const { return argument_count(); }
- virtual HValue* OperandAt(int index) const { return arguments_[index]; }
- virtual HPushArgument* PushArgumentAt(int index) const {
- return HPushArgument::cast(OperandAt(index));
+ virtual int argument_count() const { return argument_count_; }
+
+ virtual void PrintDataTo(StringStream* stream) const;
+
+ DECLARE_INSTRUCTION(Call)
+
+ private:
+ int argument_count_;
+};
+
+
+class HUnaryCall: public HCall {
+ public:
+ HUnaryCall(HValue* value, int argument_count)
+ : HCall(argument_count), value_(NULL) {
+ SetOperandAt(0, value);
+ }
+
+ virtual void PrintDataTo(StringStream* stream) const;
+
+ HValue* value() const { return value_; }
+
+ virtual int OperandCount() const { return 1; }
+ virtual HValue* OperandAt(int index) const {
+ ASSERT(index == 0);
+ return value_;
+ }
+
+ DECLARE_INSTRUCTION(UnaryCall)
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value) {
+ ASSERT(index == 0);
+ value_ = value;
}
- virtual HValue* ArgumentAt(int index) const {
- return PushArgumentAt(index)->argument();
+
+ private:
+ HValue* value_;
+};
+
+
+class HBinaryCall: public HCall {
+ public:
+ HBinaryCall(HValue* first, HValue* second, int argument_count)
+ : HCall(argument_count) {
+ SetOperandAt(0, first);
+ SetOperandAt(1, second);
}
- virtual void SetArgumentAt(int index, HPushArgument* push_argument);
virtual void PrintDataTo(StringStream* stream) const;
- DECLARE_INSTRUCTION(Call)
+ HValue* first() const { return operands_[0]; }
+ HValue* second() const { return operands_[1]; }
+
+ virtual int OperandCount() const { return 2; }
+ virtual HValue* OperandAt(int index) const { return operands_[index]; }
+
+ DECLARE_INSTRUCTION(BinaryCall)
protected:
virtual void InternalSetOperandAt(int index, HValue* value) {
- arguments_[index] = value;
+ operands_[index] = value;
}
- int argument_count_;
- Vector<HValue*> arguments_;
+ private:
+ HOperandVector<2> operands_;
};
: HCall(argument_count), function_(function) { }
Handle<JSFunction> function() const { return function_; }
+
bool IsApplyFunction() const {
return function_->code() == Builtins::builtin(Builtins::FunctionApply);
}
};
-// TODO(3190496): This class uses hacks to get additional operands that ar
-// not arguments to work with the current setup. This _needs_ a cleanup.
-// (see HCall).
-class HCallKeyed: public HCall {
+class HCallKeyed: public HBinaryCall {
public:
HCallKeyed(HValue* context, HValue* key, int argument_count)
- : HCall(argument_count + 1), context_(NULL) {
- SetOperandAt(0, key);
- SetOperandAt(argument_count + 1, context);
+ : HBinaryCall(context, key, argument_count) {
}
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- virtual void PrintDataTo(StringStream* stream) const;
-
- HValue* key() const { return OperandAt(0); }
- HValue* context() const { return context_; }
-
- virtual int argument_count() const { return arguments_.length() - 1; }
- virtual int OperandCount() const { return arguments_.length() + 1; }
-
- virtual HValue* OperandAt(int index) const {
- // The key and all the arguments are stored in the base class's
- // arguments_ vector. The context is in the object itself. Ugly.
- return (index <= argument_count()) ? arguments_[index] : context_;
- }
-
- virtual HPushArgument* PushArgumentAt(int index) const {
- return HPushArgument::cast(OperandAt(index + 1));
- }
- virtual void SetArgumentAt(int index, HPushArgument* push_argument) {
- HCall::SetArgumentAt(index + 1, push_argument);
- }
+ HValue* context() const { return first(); }
+ HValue* key() const { return second(); }
DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
-
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
- HValue* context_;
};
-class HCallNamed: public HCall {
+class HCallNamed: public HUnaryCall {
public:
HCallNamed(HValue* context, Handle<String> name, int argument_count)
- : HCall(argument_count), context_(NULL), name_(name) {
- SetOperandAt(argument_count, context);
+ : HUnaryCall(context, argument_count), name_(name) {
}
virtual void PrintDataTo(StringStream* stream) const;
- HValue* context() const { return context_; }
+ HValue* context() const { return value(); }
Handle<String> name() const { return name_; }
- virtual int OperandCount() const { return arguments_.length() + 1; }
-
- virtual HValue* OperandAt(int index) const {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- return (index < argument_count()) ? arguments_[index] : context_;
- }
-
DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value);
-
private:
- HValue* context_;
Handle<String> name_;
};
-class HCallFunction: public HCall {
+class HCallFunction: public HUnaryCall {
public:
HCallFunction(HValue* context, int argument_count)
- : HCall(argument_count), context_(NULL) {
- SetOperandAt(argument_count, context);
+ : HUnaryCall(context, argument_count) {
}
- HValue* context() const { return context_; }
-
- virtual int OperandCount() const { return arguments_.length() + 1; }
-
- virtual HValue* OperandAt(int index) const {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- return (index < argument_count()) ? arguments_[index] : context_;
- }
+ HValue* context() const { return value(); }
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
-
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
- HValue* context_;
};
-class HCallGlobal: public HCall {
+class HCallGlobal: public HUnaryCall {
public:
HCallGlobal(HValue* context, Handle<String> name, int argument_count)
- : HCall(argument_count), context_(NULL), name_(name) {
- SetOperandAt(argument_count, context);
+ : HUnaryCall(context, argument_count), name_(name) {
}
virtual void PrintDataTo(StringStream* stream) const;
- HValue* context() const { return context_; }
+ HValue* context() const { return value(); }
Handle<String> name() const { return name_; }
- virtual int OperandCount() const { return arguments_.length() + 1; }
-
- virtual HValue* OperandAt(int index) const {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- return (index < argument_count()) ? arguments_[index] : context_;
- }
-
DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value);
-
private:
- HValue* context_;
Handle<String> name_;
};
class HCallKnownGlobal: public HCall {
public:
- HCallKnownGlobal(Handle<JSFunction> target,
- int argument_count)
+ HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
: HCall(argument_count), target_(target) { }
+ virtual void PrintDataTo(StringStream* stream) const;
+
Handle<JSFunction> target() const { return target_; }
DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
};
-class HCallNew: public HCall {
+class HCallNew: public HBinaryCall {
public:
- HCallNew(HValue* context, int argument_count)
- : HCall(argument_count), context_(NULL) {
- SetOperandAt(argument_count, context);
+ HCallNew(HValue* context, HValue* constructor, int argument_count)
+ : HBinaryCall(context, constructor, argument_count) {
}
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- HValue* context() const { return context_; }
- HValue* constructor() const { return ArgumentAt(0); }
-
- virtual int OperandCount() const { return arguments_.length() + 1; }
-
- virtual HValue* OperandAt(int index) const {
- // The arguments are in the base class's arguments_ vector. The context
- // is in the object itself.
- return (index < argument_count()) ? arguments_[index] : context_;
- }
+ HValue* context() const { return first(); }
+ HValue* constructor() const { return second(); }
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
-
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value);
-
- private:
- HValue* context_;
};
};
-class HCallStub: public HUnaryOperation {
+class HCallStub: public HUnaryCall {
public:
HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
- : HUnaryOperation(context),
+ : HUnaryCall(context, argument_count),
major_key_(major_key),
- argument_count_(argument_count),
transcendental_type_(TranscendentalCache::kNumberOfCaches) {
- set_representation(Representation::Tagged());
- SetAllSideEffects();
}
CodeStub::Major major_key() { return major_key_; }
- int argument_count() { return argument_count_; }
- HValue* context() { return OperandAt(0); }
+
+ HValue* context() const { return value(); }
void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
transcendental_type_ = transcendental_type;
TranscendentalCache::Type transcendental_type() {
return transcendental_type_;
}
+
virtual void PrintDataTo(StringStream* stream) const;
DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
private:
CodeStub::Major major_key_;
- int argument_count_;
TranscendentalCache::Type transcendental_type_;
};
}
-HValue* HGraphBuilder::VisitArgument(Expression* expr) {
+void HGraphBuilder::VisitArgument(Expression* expr) {
VisitForValue(expr);
- if (HasStackOverflow() || !subgraph()->HasExit()) return NULL;
- return environment()->Top();
}
}
-void HGraphBuilder::PushArgumentsForStubCall(int argument_count) {
- const int kMaxStubArguments = 4;
- ASSERT_GE(kMaxStubArguments, argument_count);
- // Push the arguments on the stack.
- HValue* arguments[kMaxStubArguments];
- for (int i = argument_count - 1; i >= 0; i--) {
- arguments[i] = Pop();
- }
- for (int i = 0; i < argument_count; i++) {
- AddInstruction(new HPushArgument(arguments[i]));
- }
-}
-
-
-void HGraphBuilder::ProcessCall(HCall* call) {
- for (int i = call->argument_count() - 1; i >= 0; --i) {
- HValue* value = Pop();
- HPushArgument* push = new HPushArgument(value);
- call->SetArgumentAt(i, push);
+void HGraphBuilder::PreProcessCall(HCall* call) {
+ int count = call->argument_count();
+ ZoneList<HValue*> arguments(count);
+ for (int i = 0; i < count; ++i) {
+ arguments.Add(Pop());
}
- for (int i = 0; i < call->argument_count(); ++i) {
- AddInstruction(call->PushArgumentAt(i));
+ while (!arguments.is_empty()) {
+ AddInstruction(new HPushArgument(arguments.RemoveLast()));
}
}
CHECK_BAILOUT;
HCall* call = new HCallConstantFunction(expr->target(), argument_count);
call->set_position(expr->position());
- ProcessCall(call);
+ PreProcessCall(call);
PushAndAdd(call);
}
subgraphs.Add(subgraph);
AddInstruction(context);
HCall* call = new HCallNamed(context, name, argument_count);
call->set_position(expr->position());
- ProcessCall(call);
+ PreProcessCall(call);
ast_context()->ReturnInstruction(call, expr->id());
} else {
// Build subgraph for generic call through IC.
AddInstruction(context);
HCall* call = new HCallNamed(context, name, argument_count);
call->set_position(expr->position());
- ProcessCall(call);
+ PreProcessCall(call);
PushAndAdd(call);
}
subgraphs.Add(subgraph);
AddInstruction(context);
call = new HCallKeyed(context, key, argument_count);
call->set_position(expr->position());
- ProcessCall(call);
+ PreProcessCall(call);
Drop(1); // Key.
ast_context()->ReturnInstruction(call, expr->id());
return;
if (TryCallApply(expr)) return;
CHECK_BAILOUT;
- HValue* receiver = VisitArgument(prop->obj());
+ VisitArgument(prop->obj());
CHECK_BAILOUT;
VisitArgumentList(expr->arguments());
CHECK_BAILOUT;
expr->RecordTypeFeedback(oracle());
ZoneMapList* types = expr->GetReceiverTypes();
+ HValue* receiver =
+ environment()->ExpressionStackAt(expr->arguments()->length());
if (expr->IsMonomorphic()) {
Handle<Map> receiver_map =
(types == NULL) ? Handle<Map>::null() : types->first();
}
call->set_position(expr->position());
- ProcessCall(call);
+ PreProcessCall(call);
ast_context()->ReturnInstruction(call, expr->id());
}
VisitArgumentList(expr->arguments());
CHECK_BAILOUT;
- int argument_count = expr->arguments()->length() + 1; // Plus constructor.
HContext* context = new HContext;
AddInstruction(context);
- HCall* call = new HCallNew(context, argument_count);
+
+ // The constructor is both an operand to the instruction and an argument
+ // to the construct call.
+ int arg_count = expr->arguments()->length() + 1; // Plus constructor.
+ HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
+ HCall* call = new HCallNew(context, constructor, arg_count);
call->set_position(expr->position());
- ProcessCall(call);
+ PreProcessCall(call);
ast_context()->ReturnInstruction(call, expr->id());
}
ASSERT(function->intrinsic_type == Runtime::RUNTIME);
HCall* call = new HCallRuntime(name, expr->function(), argument_count);
call->set_position(RelocInfo::kNoPosition);
- ProcessCall(call);
+ PreProcessCall(call);
ast_context()->ReturnInstruction(call, expr->id());
}
}
// Fast support for string.charAt(n) and string[n].
void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) {
ASSERT_EQ(2, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::StringCharAt, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
// Fast support for StringAdd.
void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) {
ASSERT_EQ(2, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::StringAdd, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
// Fast support for SubString.
void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) {
ASSERT_EQ(3, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::SubString, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
// Fast support for StringCompare.
void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) {
ASSERT_EQ(2, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::StringCompare, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
// Support for direct calls from JavaScript to native RegExp code.
void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) {
ASSERT_EQ(4, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::RegExpExec, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
void HGraphBuilder::GenerateRegExpConstructResult(int argument_count,
int ast_id) {
ASSERT_EQ(3, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::RegExpConstructResult, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
// Fast support for number to string.
void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) {
ASSERT_EQ(1, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::NumberToString, argument_count);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) {
ASSERT_EQ(1, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::TranscendentalCache, argument_count);
result->set_transcendental_type(TranscendentalCache::SIN);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) {
ASSERT_EQ(1, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::TranscendentalCache, argument_count);
result->set_transcendental_type(TranscendentalCache::COS);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) {
ASSERT_EQ(1, argument_count);
- PushArgumentsForStubCall(argument_count);
HContext* context = new HContext;
AddInstruction(context);
HCallStub* result =
new HCallStub(context, CodeStub::TranscendentalCache, argument_count);
result->set_transcendental_type(TranscendentalCache::LOG);
+ PreProcessCall(result);
ast_context()->ReturnInstruction(result, ast_id);
}
HBasicBlock* true_block,
HBasicBlock* false_block);
- // Visit an argument and wrap it in a PushArgument instruction.
- HValue* VisitArgument(Expression* expr);
+ // Visit an argument subexpression.
+ void VisitArgument(Expression* expr);
void VisitArgumentList(ZoneList<Expression*>* arguments);
void AddPhi(HPhi* phi);
void PushAndAdd(HInstruction* instr);
- void PushArgumentsForStubCall(int argument_count);
-
// Remove the arguments from the bailout environment and emit instructions
// to push them as outgoing parameters.
- void ProcessCall(HCall* call);
+ void PreProcessCall(HCall* call);
void AssumeRepresentation(HValue* value, Representation r);
static Representation ToRepresentation(TypeInfo info);