| Index: runtime/lib/integers.cc
 | 
| diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
 | 
| index 8df13969a51561e12272fbe6d073b603be4c29e6..1d93b40e1bf471e97c5b94ae720b74d1955820bb 100644
 | 
| --- a/runtime/lib/integers.cc
 | 
| +++ b/runtime/lib/integers.cc
 | 
| @@ -4,9 +4,12 @@
 | 
|  
 | 
|  #include "vm/bootstrap_natives.h"
 | 
|  
 | 
| +#include "include/dart_api.h"
 | 
|  #include "vm/bigint_operations.h"
 | 
|  #include "vm/dart_entry.h"
 | 
| +#include "vm/dart_api_impl.h"
 | 
|  #include "vm/exceptions.h"
 | 
| +#include "vm/isolate.h"
 | 
|  #include "vm/native_entry.h"
 | 
|  #include "vm/object.h"
 | 
|  #include "vm/object_store.h"
 | 
| @@ -226,6 +229,61 @@ DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 3) {
 | 
| +  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
 | 
| +  GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2));
 | 
| +  // Call the embedder to supply us with the environment.
 | 
| +  Dart_EnvironmentCallback callback = isolate->environment_callback();
 | 
| +  if (callback != NULL) {
 | 
| +    Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
 | 
| +    if (Dart_IsError(result)) {
 | 
| +      const Object& error =
 | 
| +          Object::Handle(isolate, Api::UnwrapHandle(result));
 | 
| +      Exceptions::ThrowArgumentError(
 | 
| +          String::Handle(
 | 
| +              String::New(Error::Cast(error).ToErrorCString())));
 | 
| +    } else if (Dart_IsString(result)) {
 | 
| +      uint8_t* digits;
 | 
| +      intptr_t digits_len;
 | 
| +      Dart_StringToUTF8(result, &digits, &digits_len);
 | 
| +      if (digits_len > 0) {
 | 
| +        // Check for valid integer literal before constructing integer object.
 | 
| +        // Skip leading minus if present.
 | 
| +        if (digits[0] == '-') {
 | 
| +          digits++;
 | 
| +          digits_len--;
 | 
| +        }
 | 
| +        // Check remaining string for decimal or hex-decimal literal.
 | 
| +        bool is_number = true;
 | 
| +        if (digits_len > 2 &&
 | 
| +            digits[0] == '0' &&
 | 
| +            (digits[1] == 'x' || digits[1] == 'X')) {
 | 
| +          for (int i = 2; i < digits_len && is_number; i++) {
 | 
| +            is_number = ('0' <= digits[i] && digits[i] <= '9') ||
 | 
| +                        ('A' <= digits[i] && digits[i] <= 'F') ||
 | 
| +                        ('a' <= digits[i] && digits[i] <= 'f');
 | 
| +          }
 | 
| +        } else {
 | 
| +          for (int i = 0; i < digits_len && is_number; i++) {
 | 
| +            is_number = '0' <= digits[i] && digits[i] <= '9';
 | 
| +          }
 | 
| +        }
 | 
| +        if (digits_len > 0 && is_number) {
 | 
| +          const Object& value =
 | 
| +              Object::Handle(isolate, Api::UnwrapHandle(result));
 | 
| +          ASSERT(value.IsString());
 | 
| +          return Integer::NewCanonical(String::Cast(value));
 | 
| +        }
 | 
| +      }
 | 
| +    } else if (!Dart_IsNull(result)) {
 | 
| +      Exceptions::ThrowArgumentError(
 | 
| +          String::Handle(String::New("Illegal environment value")));
 | 
| +    }
 | 
| +  }
 | 
| +  return default_value.raw();
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // Passing true for 'silent' prevents throwing JavascriptIntegerOverflow.
 | 
|  static RawInteger* ShiftOperationHelper(Token::Kind kind,
 | 
|                                          const Integer& value,
 | 
| 
 |