Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 DEFINE_FLAG(bool, show_internal_names, false, | 45 DEFINE_FLAG(bool, show_internal_names, false, |
| 46 "Show names of internal classes (e.g. \"OneByteString\") in error messages " | 46 "Show names of internal classes (e.g. \"OneByteString\") in error messages " |
| 47 "instead of showing the corresponding interface names (e.g. \"String\")"); | 47 "instead of showing the corresponding interface names (e.g. \"String\")"); |
| 48 DEFINE_FLAG(bool, trace_disabling_optimized_code, false, | 48 DEFINE_FLAG(bool, trace_disabling_optimized_code, false, |
| 49 "Trace disabling optimized code."); | 49 "Trace disabling optimized code."); |
| 50 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, | 50 DEFINE_FLAG(int, huge_method_cutoff_in_tokens, 20000, |
| 51 "Huge method cutoff in tokens: Disables optimizations for huge methods."); | 51 "Huge method cutoff in tokens: Disables optimizations for huge methods."); |
| 52 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, | 52 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, |
| 53 "Huge method cutoff in unoptimized code size (in bytes)."); | 53 "Huge method cutoff in unoptimized code size (in bytes)."); |
| 54 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, | 54 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, |
| 55 "Throw an exception when integer arithmetic exceeds 53 bits."); | 55 "Throw an exception when integer arithmetic exceeds 54 bits."); |
| 56 DECLARE_FLAG(bool, trace_compiler); | 56 DECLARE_FLAG(bool, trace_compiler); |
| 57 DECLARE_FLAG(bool, eliminate_type_checks); | 57 DECLARE_FLAG(bool, eliminate_type_checks); |
| 58 DECLARE_FLAG(bool, enable_type_checks); | 58 DECLARE_FLAG(bool, enable_type_checks); |
| 59 | 59 |
| 60 static const char* kGetterPrefix = "get:"; | 60 static const char* kGetterPrefix = "get:"; |
| 61 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); | 61 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
| 62 static const char* kSetterPrefix = "set:"; | 62 static const char* kSetterPrefix = "set:"; |
| 63 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); | 63 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
| 64 | 64 |
| 65 cpp_vtable Object::handle_vtable_ = 0; | 65 cpp_vtable Object::handle_vtable_ = 0; |
| (...skipping 11160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11226 return "Integer"; | 11226 return "Integer"; |
| 11227 } | 11227 } |
| 11228 | 11228 |
| 11229 | 11229 |
| 11230 void Integer::PrintToJSONStream(JSONStream* stream, bool ref) const { | 11230 void Integer::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 11231 stream->OpenObject(); | 11231 stream->OpenObject(); |
| 11232 stream->CloseObject(); | 11232 stream->CloseObject(); |
| 11233 } | 11233 } |
| 11234 | 11234 |
| 11235 | 11235 |
| 11236 // Throw FiftyThreeBitOverflow exception. | 11236 // Throw FiftyFourBitOverflow exception. |
| 11237 static void ThrowFiftyThreeBitOverflow(const Integer& i) { | 11237 static void ThrowFiftyFourBitOverflow(const Integer& i) { |
| 11238 const Array& exc_args = Array::Handle(Array::New(1)); | 11238 const Array& exc_args = Array::Handle(Array::New(1)); |
| 11239 const String& i_str = String::Handle(String::New(i.ToCString())); | 11239 const String& i_str = String::Handle(String::New(i.ToCString())); |
| 11240 exc_args.SetAt(0, i_str); | 11240 exc_args.SetAt(0, i_str); |
| 11241 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args); | 11241 Exceptions::ThrowByType(Exceptions::kFiftyFourBitOverflowError, exc_args); |
| 11242 } | 11242 } |
| 11243 | 11243 |
| 11244 | 11244 |
| 11245 RawInteger* Integer::New(const String& str, Heap::Space space) { | 11245 RawInteger* Integer::New(const String& str, Heap::Space space) { |
| 11246 // We are not supposed to have integers represented as two byte strings. | 11246 // We are not supposed to have integers represented as two byte strings. |
| 11247 ASSERT(str.IsOneByteString()); | 11247 ASSERT(str.IsOneByteString()); |
| 11248 int64_t value; | 11248 int64_t value; |
| 11249 if (!OS::StringToInt64(str.ToCString(), &value)) { | 11249 if (!OS::StringToInt64(str.ToCString(), &value)) { |
| 11250 const Bigint& big = Bigint::Handle(Bigint::New(str, space)); | 11250 const Bigint& big = Bigint::Handle(Bigint::New(str, space)); |
| 11251 ASSERT(!BigintOperations::FitsIntoSmi(big)); | 11251 ASSERT(!BigintOperations::FitsIntoSmi(big)); |
| 11252 ASSERT(!BigintOperations::FitsIntoInt64(big)); | 11252 ASSERT(!BigintOperations::FitsIntoInt64(big)); |
| 11253 if (FLAG_throw_on_javascript_int_overflow) { | 11253 if (FLAG_throw_on_javascript_int_overflow) { |
| 11254 ThrowFiftyThreeBitOverflow(big); | 11254 ThrowFiftyFourBitOverflow(big); |
| 11255 } | 11255 } |
| 11256 return big.raw(); | 11256 return big.raw(); |
| 11257 } | 11257 } |
| 11258 return Integer::New(value, space); | 11258 return Integer::New(value, space); |
| 11259 } | 11259 } |
| 11260 | 11260 |
| 11261 | 11261 |
| 11262 // This is called from LiteralToken::New() in the parser, so we can't | 11262 // This is called from LiteralToken::New() in the parser, so we can't |
| 11263 // raise an exception for 53-bit overflow here. Instead we do it in | 11263 // raise an exception for 54-bit overflow here. Instead we do it in |
| 11264 // Parser::CurrentIntegerLiteral(), which is the point in the parser where | 11264 // Parser::CurrentIntegerLiteral(), which is the point in the parser where |
| 11265 // integer literals escape, so we can call Parser::ErrorMsg(). | 11265 // integer literals escape, so we can call Parser::ErrorMsg(). |
| 11266 RawInteger* Integer::NewCanonical(const String& str) { | 11266 RawInteger* Integer::NewCanonical(const String& str) { |
| 11267 // We are not supposed to have integers represented as two byte strings. | 11267 // We are not supposed to have integers represented as two byte strings. |
| 11268 ASSERT(str.IsOneByteString()); | 11268 ASSERT(str.IsOneByteString()); |
| 11269 int64_t value; | 11269 int64_t value; |
| 11270 if (!OS::StringToInt64(str.ToCString(), &value)) { | 11270 if (!OS::StringToInt64(str.ToCString(), &value)) { |
| 11271 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); | 11271 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); |
| 11272 ASSERT(!BigintOperations::FitsIntoSmi(big)); | 11272 ASSERT(!BigintOperations::FitsIntoSmi(big)); |
| 11273 ASSERT(!BigintOperations::FitsIntoInt64(big)); | 11273 ASSERT(!BigintOperations::FitsIntoInt64(big)); |
| 11274 return big.raw(); | 11274 return big.raw(); |
| 11275 } | 11275 } |
| 11276 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { | 11276 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
| 11277 return Smi::New(value); | 11277 return Smi::New(value); |
| 11278 } | 11278 } |
| 11279 return Mint::NewCanonical(value); | 11279 return Mint::NewCanonical(value); |
| 11280 } | 11280 } |
| 11281 | 11281 |
| 11282 | 11282 |
| 11283 // Floating point has a sign bit and 53 bits of fraction. When the sign bit is | |
| 11284 // set, and the fraction is 0, the result is -0.0, not MIN_53BIT_INT. | |
|
siva
2013/07/31 16:08:28
The comment here is a bit confusing as we are deal
zra
2013/07/31 17:46:31
Done.
| |
| 11285 static bool Is54BitNoMinInt(int64_t value) { | |
| 11286 return (Utils::IsInt(54, value)) && (value != (-0x1FFFFFFFFFFFFF - 1)); | |
| 11287 } | |
| 11288 | |
| 11289 | |
| 11283 RawInteger* Integer::New(int64_t value, Heap::Space space) { | 11290 RawInteger* Integer::New(int64_t value, Heap::Space space) { |
| 11284 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { | 11291 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
| 11285 return Smi::New(value); | 11292 return Smi::New(value); |
| 11286 } | 11293 } |
| 11287 if (FLAG_throw_on_javascript_int_overflow && !Utils::IsInt(53, value)) { | 11294 if (FLAG_throw_on_javascript_int_overflow && !Is54BitNoMinInt(value)) { |
| 11288 const Integer &i = Integer::Handle(Mint::New(value)); | 11295 const Integer &i = Integer::Handle(Mint::New(value)); |
| 11289 ThrowFiftyThreeBitOverflow(i); | 11296 ThrowFiftyFourBitOverflow(i); |
| 11290 } | 11297 } |
| 11291 return Mint::New(value, space); | 11298 return Mint::New(value, space); |
| 11292 } | 11299 } |
| 11293 | 11300 |
| 11294 | 11301 |
| 11295 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { | 11302 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { |
| 11296 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { | 11303 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |
| 11297 if (FLAG_throw_on_javascript_int_overflow) { | 11304 if (FLAG_throw_on_javascript_int_overflow) { |
| 11298 const Integer &i = | 11305 const Integer &i = |
| 11299 Integer::Handle(BigintOperations::NewFromUint64(value)); | 11306 Integer::Handle(BigintOperations::NewFromUint64(value)); |
| 11300 ThrowFiftyThreeBitOverflow(i); | 11307 ThrowFiftyFourBitOverflow(i); |
| 11301 } | 11308 } |
| 11302 return BigintOperations::NewFromUint64(value); | 11309 return BigintOperations::NewFromUint64(value); |
| 11303 } else { | 11310 } else { |
| 11304 return Integer::New(value); | 11311 return Integer::New(value); |
| 11305 } | 11312 } |
| 11306 } | 11313 } |
| 11307 | 11314 |
| 11308 | 11315 |
| 11309 double Integer::AsDoubleValue() const { | 11316 double Integer::AsDoubleValue() const { |
| 11310 UNIMPLEMENTED(); | 11317 UNIMPLEMENTED(); |
| 11311 return 0.0; | 11318 return 0.0; |
| 11312 } | 11319 } |
| 11313 | 11320 |
| 11314 | 11321 |
| 11315 int64_t Integer::AsInt64Value() const { | 11322 int64_t Integer::AsInt64Value() const { |
| 11316 UNIMPLEMENTED(); | 11323 UNIMPLEMENTED(); |
| 11317 return 0; | 11324 return 0; |
| 11318 } | 11325 } |
| 11319 | 11326 |
| 11320 | 11327 |
| 11321 int Integer::CompareWith(const Integer& other) const { | 11328 int Integer::CompareWith(const Integer& other) const { |
| 11322 UNIMPLEMENTED(); | 11329 UNIMPLEMENTED(); |
| 11323 return 0; | 11330 return 0; |
| 11324 } | 11331 } |
| 11325 | 11332 |
| 11326 | 11333 |
| 11327 // Returns true if the signed Integer requires more than 53 bits. | 11334 // Returns true if the signed Integer requires more than 54 bits. |
| 11328 bool Integer::CheckFiftyThreeBitOverflow() const { | 11335 bool Integer::CheckFiftyFourBitOverflow() const { |
| 11329 // Always overflow if the value doesn't fit into an int64_t. | 11336 // Always overflow if the value doesn't fit into an int64_t. |
| 11330 int64_t value = 1ULL << 63; | 11337 int64_t value = 1ULL << 63; |
| 11331 if (IsSmi()) { | 11338 if (IsSmi()) { |
| 11332 value = AsInt64Value(); | 11339 value = AsInt64Value(); |
| 11333 } else if (IsMint()) { | 11340 } else if (IsMint()) { |
| 11334 Mint& mint = Mint::Handle(); | 11341 Mint& mint = Mint::Handle(); |
| 11335 mint ^= raw(); | 11342 mint ^= raw(); |
| 11336 value = mint.value(); | 11343 value = mint.value(); |
| 11337 } else { | 11344 } else { |
| 11338 ASSERT(IsBigint()); | 11345 ASSERT(IsBigint()); |
| 11339 Bigint& big_value = Bigint::Handle(); | 11346 Bigint& big_value = Bigint::Handle(); |
| 11340 big_value ^= raw(); | 11347 big_value ^= raw(); |
| 11341 if (BigintOperations::FitsIntoInt64(big_value)) { | 11348 if (BigintOperations::FitsIntoInt64(big_value)) { |
| 11342 value = BigintOperations::ToInt64(big_value); | 11349 value = BigintOperations::ToInt64(big_value); |
| 11343 } | 11350 } |
| 11344 } | 11351 } |
| 11345 return !Utils::IsInt(53, value); | 11352 return !Is54BitNoMinInt(value); |
| 11346 } | 11353 } |
| 11347 | 11354 |
| 11348 | 11355 |
| 11349 RawInteger* Integer::AsValidInteger() const { | 11356 RawInteger* Integer::AsValidInteger() const { |
| 11350 if (FLAG_throw_on_javascript_int_overflow && | 11357 if (FLAG_throw_on_javascript_int_overflow && |
| 11351 CheckFiftyThreeBitOverflow()) { | 11358 CheckFiftyFourBitOverflow()) { |
| 11352 ThrowFiftyThreeBitOverflow(*this); | 11359 ThrowFiftyFourBitOverflow(*this); |
| 11353 } | 11360 } |
| 11354 if (IsSmi()) return raw(); | 11361 if (IsSmi()) return raw(); |
| 11355 if (IsMint()) { | 11362 if (IsMint()) { |
| 11356 Mint& mint = Mint::Handle(); | 11363 Mint& mint = Mint::Handle(); |
| 11357 mint ^= raw(); | 11364 mint ^= raw(); |
| 11358 if (Smi::IsValid64(mint.value())) { | 11365 if (Smi::IsValid64(mint.value())) { |
| 11359 return Smi::New(mint.value()); | 11366 return Smi::New(mint.value()); |
| 11360 } else { | 11367 } else { |
| 11361 return raw(); | 11368 return raw(); |
| 11362 } | 11369 } |
| (...skipping 3019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14382 } | 14389 } |
| 14383 | 14390 |
| 14384 | 14391 |
| 14385 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 14392 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
| 14386 stream->OpenObject(); | 14393 stream->OpenObject(); |
| 14387 stream->CloseObject(); | 14394 stream->CloseObject(); |
| 14388 } | 14395 } |
| 14389 | 14396 |
| 14390 | 14397 |
| 14391 } // namespace dart | 14398 } // namespace dart |
| OLD | NEW |