| Index: src/code-stubs.cc
|
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc
|
| index d472fa287f0c03c0a40180267b6da29828c16325..5f6616ea07a9d12891d824c19c03e9b8312487e3 100644
|
| --- a/src/code-stubs.cc
|
| +++ b/src/code-stubs.cc
|
| @@ -204,6 +204,71 @@ void CodeStub::PrintName(StringStream* stream) {
|
| }
|
|
|
|
|
| +Builtins::JavaScript UnaryOpStub::ToJSBuiltin() {
|
| + switch (operation_) {
|
| + default:
|
| + UNREACHABLE();
|
| + case Token::SUB:
|
| + return Builtins::UNARY_MINUS;
|
| + case Token::BIT_NOT:
|
| + return Builtins::BIT_NOT;
|
| + }
|
| +}
|
| +
|
| +
|
| +Handle<JSFunction> UnaryOpStub::ToJSFunction(Isolate* isolate) {
|
| + Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object());
|
| + Object* builtin = builtins->javascript_builtin(ToJSBuiltin());
|
| + return Handle<JSFunction>(JSFunction::cast(builtin), isolate);
|
| +}
|
| +
|
| +
|
| +MaybeObject* UnaryOpStub::Result(Handle<Object> object, Isolate* isolate) {
|
| + Handle<JSFunction> builtin_function = ToJSFunction(isolate);
|
| + bool caught_exception;
|
| + Handle<Object> result = Execution::Call(builtin_function, object,
|
| + 0, NULL, &caught_exception);
|
| + if (caught_exception) {
|
| + return Failure::Exception();
|
| + }
|
| + return *result;
|
| +}
|
| +
|
| +
|
| +void UnaryOpStub::UpdateStatus(Handle<Object> object) {
|
| + State old_state(state_);
|
| + if (object->IsSmi()) {
|
| + state_.Add(SMI);
|
| + if (operation_ == Token::SUB && *object == 0) {
|
| + // The result (-0) has to be represented as double.
|
| + state_.Add(HEAP_NUMBER);
|
| + }
|
| + } else if (object->IsHeapNumber()) {
|
| + state_.Add(HEAP_NUMBER);
|
| + } else {
|
| + state_.Add(GENERIC);
|
| + }
|
| + TraceTransition(old_state, state_);
|
| +}
|
| +
|
| +
|
| +Handle<Type> UnaryOpStub::GetType(Isolate* isolate) {
|
| + if (state_.Contains(GENERIC)) {
|
| + return handle(Type::Any(), isolate);
|
| + }
|
| + Handle<Type> type = handle(Type::None(), isolate);
|
| + if (state_.Contains(SMI)) {
|
| + type = handle(
|
| + Type::Union(type, handle(Type::Smi(), isolate)), isolate);
|
| + }
|
| + if (state_.Contains(HEAP_NUMBER)) {
|
| + type = handle(
|
| + Type::Union(type, handle(Type::Double(), isolate)), isolate);
|
| + }
|
| + return type;
|
| +}
|
| +
|
| +
|
| void BinaryOpStub::Generate(MacroAssembler* masm) {
|
| // Explicitly allow generation of nested stubs. It is safe here because
|
| // generation code does not use any raw pointers.
|
| @@ -289,6 +354,29 @@ void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
|
| #undef __
|
|
|
|
|
| +void UnaryOpStub::PrintBaseName(StringStream* stream) {
|
| + CodeStub::PrintBaseName(stream);
|
| + if (operation_ == Token::SUB) stream->Add("Minus");
|
| + if (operation_ == Token::BIT_NOT) stream->Add("Not");
|
| +}
|
| +
|
| +
|
| +void UnaryOpStub::PrintState(StringStream* stream) {
|
| + state_.Print(stream);
|
| +}
|
| +
|
| +
|
| +void UnaryOpStub::State::Print(StringStream* stream) const {
|
| + stream->Add("(");
|
| + SimpleListPrinter printer(stream);
|
| + if (IsEmpty()) printer.Add("None");
|
| + if (Contains(GENERIC)) printer.Add("Generic");
|
| + if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber");
|
| + if (Contains(SMI)) printer.Add("Smi");
|
| + stream->Add(")");
|
| +}
|
| +
|
| +
|
| void BinaryOpStub::PrintName(StringStream* stream) {
|
| const char* op_name = Token::Name(op_);
|
| const char* overwrite_name;
|
|
|