Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(671)

Side by Side Diff: src/runtime.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 ASSERT(args.length() == 2); 1201 ASSERT(args.length() == 2);
1202 CONVERT_ARG_CHECKED(JSObject, object, 0); 1202 CONVERT_ARG_CHECKED(JSObject, object, 0);
1203 CONVERT_SMI_CHECKED(properties, args[1]); 1203 CONVERT_SMI_CHECKED(properties, args[1]);
1204 if (object->HasFastProperties()) { 1204 if (object->HasFastProperties()) {
1205 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); 1205 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1206 } 1206 }
1207 return *object; 1207 return *object;
1208 } 1208 }
1209 1209
1210 1210
1211 static Object* Runtime_TransformToFastProperties(Arguments args) {
1212 HandleScope scope;
1213 ASSERT(args.length() == 1);
1214 CONVERT_ARG_CHECKED(JSObject, object, 0);
1215 if (!object->HasFastProperties() && !object->IsGlobalObject()) {
1216 TransformToFastProperties(object, 0);
1217 }
1218 return *object;
1219 }
1220
1221
1222 static Object* Runtime_RegExpExec(Arguments args) { 1211 static Object* Runtime_RegExpExec(Arguments args) {
1223 HandleScope scope; 1212 HandleScope scope;
1224 ASSERT(args.length() == 4); 1213 ASSERT(args.length() == 4);
1225 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 1214 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
1226 CONVERT_ARG_CHECKED(String, subject, 1); 1215 CONVERT_ARG_CHECKED(String, subject, 1);
1227 // Due to the way the JS calls are constructed this must be less than the 1216 // Due to the way the JS calls are constructed this must be less than the
1228 // length of a string, i.e. it is always a Smi. We check anyway for security. 1217 // length of a string, i.e. it is always a Smi. We check anyway for security.
1229 CONVERT_SMI_CHECKED(index, args[2]); 1218 CONVERT_SMI_CHECKED(index, args[2]);
1230 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); 1219 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1231 RUNTIME_ASSERT(last_match_info->HasFastElements()); 1220 RUNTIME_ASSERT(last_match_info->HasFastElements());
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
2280 schar pattern_char, 2269 schar pattern_char,
2281 int start_index) { 2270 int start_index) {
2282 for (int i = start_index, n = string.length(); i < n; i++) { 2271 for (int i = start_index, n = string.length(); i < n; i++) {
2283 if (pattern_char == string[i]) { 2272 if (pattern_char == string[i]) {
2284 return i; 2273 return i;
2285 } 2274 }
2286 } 2275 }
2287 return -1; 2276 return -1;
2288 } 2277 }
2289 2278
2279
2280 template <typename schar>
2281 static int SingleCharLastIndexOf(Vector<const schar> string,
2282 schar pattern_char,
2283 int start_index) {
2284 for (int i = start_index; i >= 0; i--) {
2285 if (pattern_char == string[i]) {
2286 return i;
2287 }
2288 }
2289 return -1;
2290 }
2291
2292
2290 // Trivial string search for shorter strings. 2293 // Trivial string search for shorter strings.
2291 // On return, if "complete" is set to true, the return value is the 2294 // On return, if "complete" is set to true, the return value is the
2292 // final result of searching for the patter in the subject. 2295 // final result of searching for the patter in the subject.
2293 // If "complete" is set to false, the return value is the index where 2296 // If "complete" is set to false, the return value is the index where
2294 // further checking should start, i.e., it's guaranteed that the pattern 2297 // further checking should start, i.e., it's guaranteed that the pattern
2295 // does not occur at a position prior to the returned index. 2298 // does not occur at a position prior to the returned index.
2296 template <typename pchar, typename schar> 2299 template <typename pchar, typename schar>
2297 static int SimpleIndexOf(Vector<const schar> subject, 2300 static int SimpleIndexOf(Vector<const schar> subject,
2298 Vector<const pchar> pattern, 2301 Vector<const pchar> pattern,
2299 int idx, 2302 int idx,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 // Dispatch to different algorithms. 2359 // Dispatch to different algorithms.
2357 template <typename schar, typename pchar> 2360 template <typename schar, typename pchar>
2358 static int StringMatchStrategy(Vector<const schar> sub, 2361 static int StringMatchStrategy(Vector<const schar> sub,
2359 Vector<const pchar> pat, 2362 Vector<const pchar> pat,
2360 int start_index) { 2363 int start_index) {
2361 ASSERT(pat.length() > 1); 2364 ASSERT(pat.length() > 1);
2362 2365
2363 // We have an ASCII haystack and a non-ASCII needle. Check if there 2366 // We have an ASCII haystack and a non-ASCII needle. Check if there
2364 // really is a non-ASCII character in the needle and bail out if there 2367 // really is a non-ASCII character in the needle and bail out if there
2365 // is. 2368 // is.
2366 if (sizeof(pchar) > 1 && sizeof(schar) == 1) { 2369 if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
2367 for (int i = 0; i < pat.length(); i++) { 2370 for (int i = 0; i < pat.length(); i++) {
2368 uc16 c = pat[i]; 2371 uc16 c = pat[i];
2369 if (c > String::kMaxAsciiCharCode) { 2372 if (c > String::kMaxAsciiCharCode) {
2370 return -1; 2373 return -1;
2371 } 2374 }
2372 } 2375 }
2373 } 2376 }
2374 if (pat.length() < kBMMinPatternLength) { 2377 if (pat.length() < kBMMinPatternLength) {
2375 // We don't believe fancy searching can ever be more efficient. 2378 // We don't believe fancy searching can ever be more efficient.
2376 // The max shift of Boyer-Moore on a pattern of this length does 2379 // The max shift of Boyer-Moore on a pattern of this length does
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 Object* index = args[2]; 2462 Object* index = args[2];
2460 uint32_t start_index; 2463 uint32_t start_index;
2461 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); 2464 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
2462 2465
2463 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); 2466 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
2464 int position = Runtime::StringMatch(sub, pat, start_index); 2467 int position = Runtime::StringMatch(sub, pat, start_index);
2465 return Smi::FromInt(position); 2468 return Smi::FromInt(position);
2466 } 2469 }
2467 2470
2468 2471
2472 template <typename schar, typename pchar>
2473 static int StringMatchBackwards(Vector<const schar> sub,
2474 Vector<const pchar> pat,
2475 int idx) {
2476 ASSERT(pat.length() >= 1);
2477 ASSERT(idx + pat.length() <= sub.length());
2478
2479 if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
2480 for (int i = 0; i < pat.length(); i++) {
2481 uc16 c = pat[i];
2482 if (c > String::kMaxAsciiCharCode) {
2483 return -1;
2484 }
2485 }
2486 }
2487
2488 pchar pattern_first_char = pat[0];
2489 for (int i = idx; i >= 0; i--) {
2490 if (sub[i] != pattern_first_char) continue;
2491 int j = 1;
2492 while (j < pat.length()) {
2493 if (pat[j] != sub[i+j]) {
2494 break;
2495 }
2496 j++;
2497 }
2498 if (j == pat.length()) {
2499 return i;
2500 }
2501 }
2502 return -1;
2503 }
2504
2469 static Object* Runtime_StringLastIndexOf(Arguments args) { 2505 static Object* Runtime_StringLastIndexOf(Arguments args) {
2470 NoHandleAllocation ha; 2506 HandleScope scope; // create a new handle scope
2471 ASSERT(args.length() == 3); 2507 ASSERT(args.length() == 3);
2472 2508
2473 CONVERT_CHECKED(String, sub, args[0]); 2509 CONVERT_ARG_CHECKED(String, sub, 0);
2474 CONVERT_CHECKED(String, pat, args[1]); 2510 CONVERT_ARG_CHECKED(String, pat, 1);
2511
2475 Object* index = args[2]; 2512 Object* index = args[2];
2476
2477 sub->TryFlattenIfNotFlat();
2478 pat->TryFlattenIfNotFlat();
2479
2480 uint32_t start_index; 2513 uint32_t start_index;
2481 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); 2514 if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
2482 2515
2483 uint32_t pattern_length = pat->length(); 2516 uint32_t pat_length = pat->length();
2484 uint32_t sub_length = sub->length(); 2517 uint32_t sub_length = sub->length();
2485 2518
2486 if (start_index + pattern_length > sub_length) { 2519 if (start_index + pat_length > sub_length) {
2487 start_index = sub_length - pattern_length; 2520 start_index = sub_length - pat_length;
2488 } 2521 }
2489 2522
2490 for (int i = start_index; i >= 0; i--) { 2523 if (pat_length == 0) {
2491 bool found = true; 2524 return Smi::FromInt(start_index);
2492 for (uint32_t j = 0; j < pattern_length; j++) {
2493 if (sub->Get(i + j) != pat->Get(j)) {
2494 found = false;
2495 break;
2496 }
2497 }
2498 if (found) return Smi::FromInt(i);
2499 } 2525 }
2500 2526
2501 return Smi::FromInt(-1); 2527 if (!sub->IsFlat()) {
2528 FlattenString(sub);
2529 }
2530
2531 if (pat_length == 1) {
2532 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
2533 if (sub->IsAsciiRepresentation()) {
2534 uc16 pchar = pat->Get(0);
2535 if (pchar > String::kMaxAsciiCharCode) {
2536 return Smi::FromInt(-1);
2537 }
2538 return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(),
2539 static_cast<char>(pat->Get(0)),
2540 start_index));
2541 } else {
2542 return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(),
2543 pat->Get(0),
2544 start_index));
2545 }
2546 }
2547
2548 if (!pat->IsFlat()) {
2549 FlattenString(pat);
2550 }
2551
2552 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
2553
2554 int position = -1;
2555
2556 if (pat->IsAsciiRepresentation()) {
2557 Vector<const char> pat_vector = pat->ToAsciiVector();
2558 if (sub->IsAsciiRepresentation()) {
2559 position = StringMatchBackwards(sub->ToAsciiVector(),
2560 pat_vector,
2561 start_index);
2562 } else {
2563 position = StringMatchBackwards(sub->ToUC16Vector(),
2564 pat_vector,
2565 start_index);
2566 }
2567 } else {
2568 Vector<const uc16> pat_vector = pat->ToUC16Vector();
2569 if (sub->IsAsciiRepresentation()) {
2570 position = StringMatchBackwards(sub->ToAsciiVector(),
2571 pat_vector,
2572 start_index);
2573 } else {
2574 position = StringMatchBackwards(sub->ToUC16Vector(),
2575 pat_vector,
2576 start_index);
2577 }
2578 }
2579
2580 return Smi::FromInt(position);
2502 } 2581 }
2503 2582
2504 2583
2505 static Object* Runtime_StringLocaleCompare(Arguments args) { 2584 static Object* Runtime_StringLocaleCompare(Arguments args) {
2506 NoHandleAllocation ha; 2585 NoHandleAllocation ha;
2507 ASSERT(args.length() == 2); 2586 ASSERT(args.length() == 2);
2508 2587
2509 CONVERT_CHECKED(String, str1, args[0]); 2588 CONVERT_CHECKED(String, str1, args[0]);
2510 CONVERT_CHECKED(String, str2, args[1]); 2589 CONVERT_CHECKED(String, str2, args[1]);
2511 2590
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 int unchecked = flag_attr->value(); 2978 int unchecked = flag_attr->value();
2900 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 2979 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
2901 RUNTIME_ASSERT(!obj->IsNull()); 2980 RUNTIME_ASSERT(!obj->IsNull());
2902 LookupResult result; 2981 LookupResult result;
2903 obj->LocalLookupRealNamedProperty(name, &result); 2982 obj->LocalLookupRealNamedProperty(name, &result);
2904 2983
2905 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 2984 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
2906 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION 2985 // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
2907 // delete it to avoid running into trouble in DefineAccessor, which 2986 // delete it to avoid running into trouble in DefineAccessor, which
2908 // handles this incorrectly if the property is readonly (does nothing) 2987 // handles this incorrectly if the property is readonly (does nothing)
2909 if (result.IsValid() && 2988 if (result.IsProperty() &&
2910 (result.type() == FIELD || result.type() == NORMAL 2989 (result.type() == FIELD || result.type() == NORMAL
2911 || result.type() == CONSTANT_FUNCTION)) { 2990 || result.type() == CONSTANT_FUNCTION)) {
2912 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); 2991 obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
2913 } 2992 }
2914 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); 2993 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
2915 } 2994 }
2916 2995
2917 static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) { 2996 static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) {
2918 ASSERT(args.length() == 4); 2997 ASSERT(args.length() == 4);
2919 HandleScope scope; 2998 HandleScope scope;
(...skipping 10 matching lines...) Expand all
2930 3009
2931 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 3010 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
2932 3011
2933 // Take special care when attributes are different and there is already 3012 // Take special care when attributes are different and there is already
2934 // a property. For simplicity we normalize the property which enables us 3013 // a property. For simplicity we normalize the property which enables us
2935 // to not worry about changing the instance_descriptor and creating a new 3014 // to not worry about changing the instance_descriptor and creating a new
2936 // map. The current version of SetObjectProperty does not handle attributes 3015 // map. The current version of SetObjectProperty does not handle attributes
2937 // correctly in the case where a property is a field and is reset with 3016 // correctly in the case where a property is a field and is reset with
2938 // new attributes. 3017 // new attributes.
2939 if (result.IsProperty() && attr != result.GetAttributes()) { 3018 if (result.IsProperty() && attr != result.GetAttributes()) {
2940 PropertyDetails details = PropertyDetails(attr, NORMAL);
2941 // New attributes - normalize to avoid writing to instance descriptor 3019 // New attributes - normalize to avoid writing to instance descriptor
2942 js_object->NormalizeProperties(KEEP_INOBJECT_PROPERTIES, 0); 3020 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2943 return js_object->SetNormalizedProperty(*name, *obj_value, details); 3021 // Use IgnoreAttributes version since a readonly property may be
3022 // overridden and SetProperty does not allow this.
3023 return js_object->IgnoreAttributesAndSetLocalProperty(*name,
3024 *obj_value,
3025 attr);
2944 } 3026 }
2945
2946 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); 3027 return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
2947 } 3028 }
2948 3029
2949 3030
2950 Object* Runtime::SetObjectProperty(Handle<Object> object, 3031 Object* Runtime::SetObjectProperty(Handle<Object> object,
2951 Handle<Object> key, 3032 Handle<Object> key,
2952 Handle<Object> value, 3033 Handle<Object> value,
2953 PropertyAttributes attr) { 3034 PropertyAttributes attr) {
2954 HandleScope scope; 3035 HandleScope scope;
2955 3036
2956 if (object->IsUndefined() || object->IsNull()) { 3037 if (object->IsUndefined() || object->IsNull()) {
2957 Handle<Object> args[2] = { key, object }; 3038 Handle<Object> args[2] = { key, object };
2958 Handle<Object> error = 3039 Handle<Object> error =
2959 Factory::NewTypeError("non_object_property_store", 3040 Factory::NewTypeError("non_object_property_store",
2960 HandleVector(args, 2)); 3041 HandleVector(args, 2));
2961 return Top::Throw(*error); 3042 return Top::Throw(*error);
2962 } 3043 }
2963 3044
2964 // If the object isn't a JavaScript object, we ignore the store. 3045 // If the object isn't a JavaScript object, we ignore the store.
2965 if (!object->IsJSObject()) return *value; 3046 if (!object->IsJSObject()) return *value;
2966 3047
2967 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 3048 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
2968 3049
2969 // Check if the given key is an array index. 3050 // Check if the given key is an array index.
2970 uint32_t index; 3051 uint32_t index;
2971 if (Array::IndexFromObject(*key, &index)) { 3052 if (Array::IndexFromObject(*key, &index)) {
2972 ASSERT(attr == NONE);
2973
2974 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 3053 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
2975 // of a string using [] notation. We need to support this too in 3054 // of a string using [] notation. We need to support this too in
2976 // JavaScript. 3055 // JavaScript.
2977 // In the case of a String object we just need to redirect the assignment to 3056 // In the case of a String object we just need to redirect the assignment to
2978 // the underlying string if the index is in range. Since the underlying 3057 // the underlying string if the index is in range. Since the underlying
2979 // string does nothing with the assignment then we can ignore such 3058 // string does nothing with the assignment then we can ignore such
2980 // assignments. 3059 // assignments.
2981 if (js_object->IsStringObjectWithCharacterAt(index)) { 3060 if (js_object->IsStringObjectWithCharacterAt(index)) {
2982 return *value; 3061 return *value;
2983 } 3062 }
2984 3063
2985 Handle<Object> result = SetElement(js_object, index, value); 3064 Handle<Object> result = SetElement(js_object, index, value);
2986 if (result.is_null()) return Failure::Exception(); 3065 if (result.is_null()) return Failure::Exception();
2987 return *value; 3066 return *value;
2988 } 3067 }
2989 3068
2990 if (key->IsString()) { 3069 if (key->IsString()) {
2991 Handle<Object> result; 3070 Handle<Object> result;
2992 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 3071 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
2993 ASSERT(attr == NONE);
2994 result = SetElement(js_object, index, value); 3072 result = SetElement(js_object, index, value);
2995 } else { 3073 } else {
2996 Handle<String> key_string = Handle<String>::cast(key); 3074 Handle<String> key_string = Handle<String>::cast(key);
2997 key_string->TryFlattenIfNotFlat(); 3075 key_string->TryFlattenIfNotFlat();
2998 result = SetProperty(js_object, key_string, value, attr); 3076 result = SetProperty(js_object, key_string, value, attr);
2999 } 3077 }
3000 if (result.is_null()) return Failure::Exception(); 3078 if (result.is_null()) return Failure::Exception();
3001 return *value; 3079 return *value;
3002 } 3080 }
3003 3081
3004 // Call-back into JavaScript to convert the key to a string. 3082 // Call-back into JavaScript to convert the key to a string.
3005 bool has_pending_exception = false; 3083 bool has_pending_exception = false;
3006 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 3084 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
3007 if (has_pending_exception) return Failure::Exception(); 3085 if (has_pending_exception) return Failure::Exception();
3008 Handle<String> name = Handle<String>::cast(converted); 3086 Handle<String> name = Handle<String>::cast(converted);
3009 3087
3010 if (name->AsArrayIndex(&index)) { 3088 if (name->AsArrayIndex(&index)) {
3011 ASSERT(attr == NONE);
3012 return js_object->SetElement(index, *value); 3089 return js_object->SetElement(index, *value);
3013 } else { 3090 } else {
3014 return js_object->SetProperty(*name, *value, attr); 3091 return js_object->SetProperty(*name, *value, attr);
3015 } 3092 }
3016 } 3093 }
3017 3094
3018 3095
3019 Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object, 3096 Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
3020 Handle<Object> key, 3097 Handle<Object> key,
3021 Handle<Object> value, 3098 Handle<Object> value,
3022 PropertyAttributes attr) { 3099 PropertyAttributes attr) {
3023 HandleScope scope; 3100 HandleScope scope;
3024 3101
3025 // Check if the given key is an array index. 3102 // Check if the given key is an array index.
3026 uint32_t index; 3103 uint32_t index;
3027 if (Array::IndexFromObject(*key, &index)) { 3104 if (Array::IndexFromObject(*key, &index)) {
3028 ASSERT(attr == NONE);
3029
3030 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 3105 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
3031 // of a string using [] notation. We need to support this too in 3106 // of a string using [] notation. We need to support this too in
3032 // JavaScript. 3107 // JavaScript.
3033 // In the case of a String object we just need to redirect the assignment to 3108 // In the case of a String object we just need to redirect the assignment to
3034 // the underlying string if the index is in range. Since the underlying 3109 // the underlying string if the index is in range. Since the underlying
3035 // string does nothing with the assignment then we can ignore such 3110 // string does nothing with the assignment then we can ignore such
3036 // assignments. 3111 // assignments.
3037 if (js_object->IsStringObjectWithCharacterAt(index)) { 3112 if (js_object->IsStringObjectWithCharacterAt(index)) {
3038 return *value; 3113 return *value;
3039 } 3114 }
3040 3115
3041 return js_object->SetElement(index, *value); 3116 return js_object->SetElement(index, *value);
3042 } 3117 }
3043 3118
3044 if (key->IsString()) { 3119 if (key->IsString()) {
3045 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 3120 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
3046 ASSERT(attr == NONE);
3047 return js_object->SetElement(index, *value); 3121 return js_object->SetElement(index, *value);
3048 } else { 3122 } else {
3049 Handle<String> key_string = Handle<String>::cast(key); 3123 Handle<String> key_string = Handle<String>::cast(key);
3050 key_string->TryFlattenIfNotFlat(); 3124 key_string->TryFlattenIfNotFlat();
3051 return js_object->IgnoreAttributesAndSetLocalProperty(*key_string, 3125 return js_object->IgnoreAttributesAndSetLocalProperty(*key_string,
3052 *value, 3126 *value,
3053 attr); 3127 attr);
3054 } 3128 }
3055 } 3129 }
3056 3130
3057 // Call-back into JavaScript to convert the key to a string. 3131 // Call-back into JavaScript to convert the key to a string.
3058 bool has_pending_exception = false; 3132 bool has_pending_exception = false;
3059 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 3133 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
3060 if (has_pending_exception) return Failure::Exception(); 3134 if (has_pending_exception) return Failure::Exception();
3061 Handle<String> name = Handle<String>::cast(converted); 3135 Handle<String> name = Handle<String>::cast(converted);
3062 3136
3063 if (name->AsArrayIndex(&index)) { 3137 if (name->AsArrayIndex(&index)) {
3064 ASSERT(attr == NONE);
3065 return js_object->SetElement(index, *value); 3138 return js_object->SetElement(index, *value);
3066 } else { 3139 } else {
3067 return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr); 3140 return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr);
3068 } 3141 }
3069 } 3142 }
3070 3143
3071 3144
3072 Object* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, 3145 Object* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object,
3073 Handle<Object> key) { 3146 Handle<Object> key) {
3074 HandleScope scope; 3147 HandleScope scope;
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
3513 // Handle special arguments properties. 3586 // Handle special arguments properties.
3514 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n); 3587 if (key->Equals(Heap::length_symbol())) return Smi::FromInt(n);
3515 if (key->Equals(Heap::callee_symbol())) return frame->function(); 3588 if (key->Equals(Heap::callee_symbol())) return frame->function();
3516 3589
3517 // Lookup in the initial Object.prototype object. 3590 // Lookup in the initial Object.prototype object.
3518 return Top::initial_object_prototype()->GetProperty(*key); 3591 return Top::initial_object_prototype()->GetProperty(*key);
3519 } 3592 }
3520 3593
3521 3594
3522 static Object* Runtime_ToFastProperties(Arguments args) { 3595 static Object* Runtime_ToFastProperties(Arguments args) {
3596 HandleScope scope;
3597
3523 ASSERT(args.length() == 1); 3598 ASSERT(args.length() == 1);
3524 Handle<Object> object = args.at<Object>(0); 3599 Handle<Object> object = args.at<Object>(0);
3525 if (object->IsJSObject()) { 3600 if (object->IsJSObject()) {
3526 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 3601 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
3527 js_object->TransformToFastProperties(0); 3602 if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) {
3603 js_object->TransformToFastProperties(0);
3604 }
3528 } 3605 }
3529 return *object; 3606 return *object;
3530 } 3607 }
3531 3608
3532 3609
3533 static Object* Runtime_ToSlowProperties(Arguments args) { 3610 static Object* Runtime_ToSlowProperties(Arguments args) {
3611 HandleScope scope;
3612
3534 ASSERT(args.length() == 1); 3613 ASSERT(args.length() == 1);
3535 Handle<Object> object = args.at<Object>(0); 3614 Handle<Object> object = args.at<Object>(0);
3536 if (object->IsJSObject()) { 3615 if (object->IsJSObject()) {
3537 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 3616 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
3538 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 3617 js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
3539 } 3618 }
3540 return *object; 3619 return *object;
3541 } 3620 }
3542 3621
3543 3622
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after
4552 // x is (non-trivial) prefix of y: 4631 // x is (non-trivial) prefix of y:
4553 if (bufy.has_more()) return Smi::FromInt(LESS); 4632 if (bufy.has_more()) return Smi::FromInt(LESS);
4554 // y is prefix of x: 4633 // y is prefix of x:
4555 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL); 4634 return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
4556 } 4635 }
4557 4636
4558 4637
4559 static Object* Runtime_Math_abs(Arguments args) { 4638 static Object* Runtime_Math_abs(Arguments args) {
4560 NoHandleAllocation ha; 4639 NoHandleAllocation ha;
4561 ASSERT(args.length() == 1); 4640 ASSERT(args.length() == 1);
4641 Counters::math_abs.Increment();
4562 4642
4563 CONVERT_DOUBLE_CHECKED(x, args[0]); 4643 CONVERT_DOUBLE_CHECKED(x, args[0]);
4564 return Heap::AllocateHeapNumber(fabs(x)); 4644 return Heap::AllocateHeapNumber(fabs(x));
4565 } 4645 }
4566 4646
4567 4647
4568 static Object* Runtime_Math_acos(Arguments args) { 4648 static Object* Runtime_Math_acos(Arguments args) {
4569 NoHandleAllocation ha; 4649 NoHandleAllocation ha;
4570 ASSERT(args.length() == 1); 4650 ASSERT(args.length() == 1);
4651 Counters::math_acos.Increment();
4571 4652
4572 CONVERT_DOUBLE_CHECKED(x, args[0]); 4653 CONVERT_DOUBLE_CHECKED(x, args[0]);
4573 return TranscendentalCache::Get(TranscendentalCache::ACOS, x); 4654 return TranscendentalCache::Get(TranscendentalCache::ACOS, x);
4574 } 4655 }
4575 4656
4576 4657
4577 static Object* Runtime_Math_asin(Arguments args) { 4658 static Object* Runtime_Math_asin(Arguments args) {
4578 NoHandleAllocation ha; 4659 NoHandleAllocation ha;
4579 ASSERT(args.length() == 1); 4660 ASSERT(args.length() == 1);
4661 Counters::math_asin.Increment();
4580 4662
4581 CONVERT_DOUBLE_CHECKED(x, args[0]); 4663 CONVERT_DOUBLE_CHECKED(x, args[0]);
4582 return TranscendentalCache::Get(TranscendentalCache::ASIN, x); 4664 return TranscendentalCache::Get(TranscendentalCache::ASIN, x);
4583 } 4665 }
4584 4666
4585 4667
4586 static Object* Runtime_Math_atan(Arguments args) { 4668 static Object* Runtime_Math_atan(Arguments args) {
4587 NoHandleAllocation ha; 4669 NoHandleAllocation ha;
4588 ASSERT(args.length() == 1); 4670 ASSERT(args.length() == 1);
4671 Counters::math_atan.Increment();
4589 4672
4590 CONVERT_DOUBLE_CHECKED(x, args[0]); 4673 CONVERT_DOUBLE_CHECKED(x, args[0]);
4591 return TranscendentalCache::Get(TranscendentalCache::ATAN, x); 4674 return TranscendentalCache::Get(TranscendentalCache::ATAN, x);
4592 } 4675 }
4593 4676
4594 4677
4595 static Object* Runtime_Math_atan2(Arguments args) { 4678 static Object* Runtime_Math_atan2(Arguments args) {
4596 NoHandleAllocation ha; 4679 NoHandleAllocation ha;
4597 ASSERT(args.length() == 2); 4680 ASSERT(args.length() == 2);
4681 Counters::math_atan2.Increment();
4598 4682
4599 CONVERT_DOUBLE_CHECKED(x, args[0]); 4683 CONVERT_DOUBLE_CHECKED(x, args[0]);
4600 CONVERT_DOUBLE_CHECKED(y, args[1]); 4684 CONVERT_DOUBLE_CHECKED(y, args[1]);
4601 double result; 4685 double result;
4602 if (isinf(x) && isinf(y)) { 4686 if (isinf(x) && isinf(y)) {
4603 // Make sure that the result in case of two infinite arguments 4687 // Make sure that the result in case of two infinite arguments
4604 // is a multiple of Pi / 4. The sign of the result is determined 4688 // is a multiple of Pi / 4. The sign of the result is determined
4605 // by the first argument (x) and the sign of the second argument 4689 // by the first argument (x) and the sign of the second argument
4606 // determines the multiplier: one or three. 4690 // determines the multiplier: one or three.
4607 static double kPiDividedBy4 = 0.78539816339744830962; 4691 static double kPiDividedBy4 = 0.78539816339744830962;
4608 int multiplier = (x < 0) ? -1 : 1; 4692 int multiplier = (x < 0) ? -1 : 1;
4609 if (y < 0) multiplier *= 3; 4693 if (y < 0) multiplier *= 3;
4610 result = multiplier * kPiDividedBy4; 4694 result = multiplier * kPiDividedBy4;
4611 } else { 4695 } else {
4612 result = atan2(x, y); 4696 result = atan2(x, y);
4613 } 4697 }
4614 return Heap::AllocateHeapNumber(result); 4698 return Heap::AllocateHeapNumber(result);
4615 } 4699 }
4616 4700
4617 4701
4618 static Object* Runtime_Math_ceil(Arguments args) { 4702 static Object* Runtime_Math_ceil(Arguments args) {
4619 NoHandleAllocation ha; 4703 NoHandleAllocation ha;
4620 ASSERT(args.length() == 1); 4704 ASSERT(args.length() == 1);
4705 Counters::math_ceil.Increment();
4621 4706
4622 CONVERT_DOUBLE_CHECKED(x, args[0]); 4707 CONVERT_DOUBLE_CHECKED(x, args[0]);
4623 return Heap::NumberFromDouble(ceiling(x)); 4708 return Heap::NumberFromDouble(ceiling(x));
4624 } 4709 }
4625 4710
4626 4711
4627 static Object* Runtime_Math_cos(Arguments args) { 4712 static Object* Runtime_Math_cos(Arguments args) {
4628 NoHandleAllocation ha; 4713 NoHandleAllocation ha;
4629 ASSERT(args.length() == 1); 4714 ASSERT(args.length() == 1);
4715 Counters::math_cos.Increment();
4630 4716
4631 CONVERT_DOUBLE_CHECKED(x, args[0]); 4717 CONVERT_DOUBLE_CHECKED(x, args[0]);
4632 return TranscendentalCache::Get(TranscendentalCache::COS, x); 4718 return TranscendentalCache::Get(TranscendentalCache::COS, x);
4633 } 4719 }
4634 4720
4635 4721
4636 static Object* Runtime_Math_exp(Arguments args) { 4722 static Object* Runtime_Math_exp(Arguments args) {
4637 NoHandleAllocation ha; 4723 NoHandleAllocation ha;
4638 ASSERT(args.length() == 1); 4724 ASSERT(args.length() == 1);
4725 Counters::math_exp.Increment();
4639 4726
4640 CONVERT_DOUBLE_CHECKED(x, args[0]); 4727 CONVERT_DOUBLE_CHECKED(x, args[0]);
4641 return TranscendentalCache::Get(TranscendentalCache::EXP, x); 4728 return TranscendentalCache::Get(TranscendentalCache::EXP, x);
4642 } 4729 }
4643 4730
4644 4731
4645 static Object* Runtime_Math_floor(Arguments args) { 4732 static Object* Runtime_Math_floor(Arguments args) {
4646 NoHandleAllocation ha; 4733 NoHandleAllocation ha;
4647 ASSERT(args.length() == 1); 4734 ASSERT(args.length() == 1);
4735 Counters::math_floor.Increment();
4648 4736
4649 CONVERT_DOUBLE_CHECKED(x, args[0]); 4737 CONVERT_DOUBLE_CHECKED(x, args[0]);
4650 return Heap::NumberFromDouble(floor(x)); 4738 return Heap::NumberFromDouble(floor(x));
4651 } 4739 }
4652 4740
4653 4741
4654 static Object* Runtime_Math_log(Arguments args) { 4742 static Object* Runtime_Math_log(Arguments args) {
4655 NoHandleAllocation ha; 4743 NoHandleAllocation ha;
4656 ASSERT(args.length() == 1); 4744 ASSERT(args.length() == 1);
4745 Counters::math_log.Increment();
4657 4746
4658 CONVERT_DOUBLE_CHECKED(x, args[0]); 4747 CONVERT_DOUBLE_CHECKED(x, args[0]);
4659 return TranscendentalCache::Get(TranscendentalCache::LOG, x); 4748 return TranscendentalCache::Get(TranscendentalCache::LOG, x);
4660 } 4749 }
4661 4750
4662 4751
4663 // Helper function to compute x^y, where y is known to be an 4752 // Helper function to compute x^y, where y is known to be an
4664 // integer. Uses binary decomposition to limit the number of 4753 // integer. Uses binary decomposition to limit the number of
4665 // multiplications; see the discussion in "Hacker's Delight" by Henry 4754 // multiplications; see the discussion in "Hacker's Delight" by Henry
4666 // S. Warren, Jr., figure 11-6, page 213. 4755 // S. Warren, Jr., figure 11-6, page 213.
(...skipping 20 matching lines...) Expand all
4687 } 4776 }
4688 } 4777 }
4689 m *= m; 4778 m *= m;
4690 } 4779 }
4691 } 4780 }
4692 4781
4693 4782
4694 static Object* Runtime_Math_pow(Arguments args) { 4783 static Object* Runtime_Math_pow(Arguments args) {
4695 NoHandleAllocation ha; 4784 NoHandleAllocation ha;
4696 ASSERT(args.length() == 2); 4785 ASSERT(args.length() == 2);
4786 Counters::math_pow.Increment();
4697 4787
4698 CONVERT_DOUBLE_CHECKED(x, args[0]); 4788 CONVERT_DOUBLE_CHECKED(x, args[0]);
4699 4789
4700 // If the second argument is a smi, it is much faster to call the 4790 // If the second argument is a smi, it is much faster to call the
4701 // custom powi() function than the generic pow(). 4791 // custom powi() function than the generic pow().
4702 if (args[1]->IsSmi()) { 4792 if (args[1]->IsSmi()) {
4703 int y = Smi::cast(args[1])->value(); 4793 int y = Smi::cast(args[1])->value();
4704 return Heap::AllocateHeapNumber(powi(x, y)); 4794 return Heap::AllocateHeapNumber(powi(x, y));
4705 } 4795 }
4706 4796
(...skipping 18 matching lines...) Expand all
4725 return Heap::nan_value(); 4815 return Heap::nan_value();
4726 } else { 4816 } else {
4727 return Heap::AllocateHeapNumber(pow(x, y)); 4817 return Heap::AllocateHeapNumber(pow(x, y));
4728 } 4818 }
4729 } 4819 }
4730 4820
4731 4821
4732 static Object* Runtime_Math_round(Arguments args) { 4822 static Object* Runtime_Math_round(Arguments args) {
4733 NoHandleAllocation ha; 4823 NoHandleAllocation ha;
4734 ASSERT(args.length() == 1); 4824 ASSERT(args.length() == 1);
4825 Counters::math_round.Increment();
4735 4826
4736 CONVERT_DOUBLE_CHECKED(x, args[0]); 4827 CONVERT_DOUBLE_CHECKED(x, args[0]);
4737 if (signbit(x) && x >= -0.5) return Heap::minus_zero_value(); 4828 if (signbit(x) && x >= -0.5) return Heap::minus_zero_value();
4738 double integer = ceil(x); 4829 double integer = ceil(x);
4739 if (integer - x > 0.5) { integer -= 1.0; } 4830 if (integer - x > 0.5) { integer -= 1.0; }
4740 return Heap::NumberFromDouble(integer); 4831 return Heap::NumberFromDouble(integer);
4741 } 4832 }
4742 4833
4743 4834
4744 static Object* Runtime_Math_sin(Arguments args) { 4835 static Object* Runtime_Math_sin(Arguments args) {
4745 NoHandleAllocation ha; 4836 NoHandleAllocation ha;
4746 ASSERT(args.length() == 1); 4837 ASSERT(args.length() == 1);
4838 Counters::math_sin.Increment();
4747 4839
4748 CONVERT_DOUBLE_CHECKED(x, args[0]); 4840 CONVERT_DOUBLE_CHECKED(x, args[0]);
4749 return TranscendentalCache::Get(TranscendentalCache::SIN, x); 4841 return TranscendentalCache::Get(TranscendentalCache::SIN, x);
4750 } 4842 }
4751 4843
4752 4844
4753 static Object* Runtime_Math_sqrt(Arguments args) { 4845 static Object* Runtime_Math_sqrt(Arguments args) {
4754 NoHandleAllocation ha; 4846 NoHandleAllocation ha;
4755 ASSERT(args.length() == 1); 4847 ASSERT(args.length() == 1);
4848 Counters::math_sqrt.Increment();
4756 4849
4757 CONVERT_DOUBLE_CHECKED(x, args[0]); 4850 CONVERT_DOUBLE_CHECKED(x, args[0]);
4758 return Heap::AllocateHeapNumber(sqrt(x)); 4851 return Heap::AllocateHeapNumber(sqrt(x));
4759 } 4852 }
4760 4853
4761 4854
4762 static Object* Runtime_Math_tan(Arguments args) { 4855 static Object* Runtime_Math_tan(Arguments args) {
4763 NoHandleAllocation ha; 4856 NoHandleAllocation ha;
4764 ASSERT(args.length() == 1); 4857 ASSERT(args.length() == 1);
4858 Counters::math_tan.Increment();
4765 4859
4766 CONVERT_DOUBLE_CHECKED(x, args[0]); 4860 CONVERT_DOUBLE_CHECKED(x, args[0]);
4767 return TranscendentalCache::Get(TranscendentalCache::TAN, x); 4861 return TranscendentalCache::Get(TranscendentalCache::TAN, x);
4768 } 4862 }
4769 4863
4770 4864
4771 // The NewArguments function is only used when constructing the
4772 // arguments array when calling non-functions from JavaScript in
4773 // runtime.js:CALL_NON_FUNCTION.
4774 static Object* Runtime_NewArguments(Arguments args) {
4775 NoHandleAllocation ha;
4776 ASSERT(args.length() == 1);
4777
4778 // ECMA-262, 3rd., 10.1.8, p.39
4779 CONVERT_CHECKED(JSFunction, callee, args[0]);
4780
4781 // Compute the frame holding the arguments.
4782 JavaScriptFrameIterator it;
4783 it.AdvanceToArgumentsFrame();
4784 JavaScriptFrame* frame = it.frame();
4785
4786 const int length = frame->GetProvidedParametersCount();
4787 Object* result = Heap::AllocateArgumentsObject(callee, length);
4788 if (result->IsFailure()) return result;
4789 if (length > 0) {
4790 Object* obj = Heap::AllocateFixedArray(length);
4791 if (obj->IsFailure()) return obj;
4792 FixedArray* array = FixedArray::cast(obj);
4793 ASSERT(array->length() == length);
4794
4795 AssertNoAllocation no_gc;
4796 WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
4797 for (int i = 0; i < length; i++) {
4798 array->set(i, frame->GetParameter(i), mode);
4799 }
4800 JSObject::cast(result)->set_elements(array);
4801 }
4802 return result;
4803 }
4804
4805
4806 static Object* Runtime_NewArgumentsFast(Arguments args) { 4865 static Object* Runtime_NewArgumentsFast(Arguments args) {
4807 NoHandleAllocation ha; 4866 NoHandleAllocation ha;
4808 ASSERT(args.length() == 3); 4867 ASSERT(args.length() == 3);
4809 4868
4810 JSFunction* callee = JSFunction::cast(args[0]); 4869 JSFunction* callee = JSFunction::cast(args[0]);
4811 Object** parameters = reinterpret_cast<Object**>(args[1]); 4870 Object** parameters = reinterpret_cast<Object**>(args[1]);
4812 const int length = Smi::cast(args[2])->value(); 4871 const int length = Smi::cast(args[2])->value();
4813 4872
4814 Object* result = Heap::AllocateArgumentsObject(callee, length); 4873 Object* result = Heap::AllocateArgumentsObject(callee, length);
4815 if (result->IsFailure()) return result; 4874 if (result->IsFailure()) return result;
(...skipping 26 matching lines...) Expand all
4842 4901
4843 PretenureFlag pretenure = (context->global_context() == *context) 4902 PretenureFlag pretenure = (context->global_context() == *context)
4844 ? TENURED // Allocate global closures in old space. 4903 ? TENURED // Allocate global closures in old space.
4845 : NOT_TENURED; // Allocate local closures in new space. 4904 : NOT_TENURED; // Allocate local closures in new space.
4846 Handle<JSFunction> result = 4905 Handle<JSFunction> result =
4847 Factory::NewFunctionFromBoilerplate(boilerplate, context, pretenure); 4906 Factory::NewFunctionFromBoilerplate(boilerplate, context, pretenure);
4848 return *result; 4907 return *result;
4849 } 4908 }
4850 4909
4851 4910
4852 static Code* ComputeConstructStub(Handle<SharedFunctionInfo> shared) { 4911 static Code* ComputeConstructStub(Handle<JSFunction> function) {
4853 // TODO(385): Change this to create a construct stub specialized for 4912 Handle<Object> prototype = Factory::null_value();
4854 // the given map to make allocation of simple objects - and maybe 4913 if (function->has_instance_prototype()) {
4855 // arrays - much faster. 4914 prototype = Handle<Object>(function->instance_prototype());
4856 if (FLAG_inline_new 4915 }
4857 && shared->has_only_simple_this_property_assignments()) { 4916 if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
4858 ConstructStubCompiler compiler; 4917 ConstructStubCompiler compiler;
4859 Object* code = compiler.CompileConstructStub(*shared); 4918 Object* code = compiler.CompileConstructStub(function->shared());
4860 if (code->IsFailure()) { 4919 if (code->IsFailure()) {
4861 return Builtins::builtin(Builtins::JSConstructStubGeneric); 4920 return Builtins::builtin(Builtins::JSConstructStubGeneric);
4862 } 4921 }
4863 return Code::cast(code); 4922 return Code::cast(code);
4864 } 4923 }
4865 4924
4866 return shared->construct_stub(); 4925 return function->shared()->construct_stub();
4867 } 4926 }
4868 4927
4869 4928
4870 static Object* Runtime_NewObject(Arguments args) { 4929 static Object* Runtime_NewObject(Arguments args) {
4871 HandleScope scope; 4930 HandleScope scope;
4872 ASSERT(args.length() == 1); 4931 ASSERT(args.length() == 1);
4873 4932
4874 Handle<Object> constructor = args.at<Object>(0); 4933 Handle<Object> constructor = args.at<Object>(0);
4875 4934
4876 // If the constructor isn't a proper function we throw a type error. 4935 // If the constructor isn't a proper function we throw a type error.
(...skipping 29 matching lines...) Expand all
4906 } 4965 }
4907 } 4966 }
4908 4967
4909 // The function should be compiled for the optimization hints to be available. 4968 // The function should be compiled for the optimization hints to be available.
4910 Handle<SharedFunctionInfo> shared(function->shared()); 4969 Handle<SharedFunctionInfo> shared(function->shared());
4911 EnsureCompiled(shared, CLEAR_EXCEPTION); 4970 EnsureCompiled(shared, CLEAR_EXCEPTION);
4912 4971
4913 bool first_allocation = !function->has_initial_map(); 4972 bool first_allocation = !function->has_initial_map();
4914 Handle<JSObject> result = Factory::NewJSObject(function); 4973 Handle<JSObject> result = Factory::NewJSObject(function);
4915 if (first_allocation) { 4974 if (first_allocation) {
4916 Handle<Map> map = Handle<Map>(function->initial_map());
4917 Handle<Code> stub = Handle<Code>( 4975 Handle<Code> stub = Handle<Code>(
4918 ComputeConstructStub(Handle<SharedFunctionInfo>(function->shared()))); 4976 ComputeConstructStub(Handle<JSFunction>(function)));
4919 function->shared()->set_construct_stub(*stub); 4977 shared->set_construct_stub(*stub);
4920 } 4978 }
4921 4979
4922 Counters::constructed_objects.Increment(); 4980 Counters::constructed_objects.Increment();
4923 Counters::constructed_objects_runtime.Increment(); 4981 Counters::constructed_objects_runtime.Increment();
4924 4982
4925 return *result; 4983 return *result;
4926 } 4984 }
4927 4985
4928 4986
4929 static Object* Runtime_LazyCompile(Arguments args) { 4987 static Object* Runtime_LazyCompile(Arguments args) {
(...skipping 18 matching lines...) Expand all
4948 // be in loops. We compile them as if they are in loops here just in case. 5006 // be in loops. We compile them as if they are in loops here just in case.
4949 ASSERT(!function->is_compiled()); 5007 ASSERT(!function->is_compiled());
4950 if (!CompileLazyInLoop(function, Handle<Object>::null(), KEEP_EXCEPTION)) { 5008 if (!CompileLazyInLoop(function, Handle<Object>::null(), KEEP_EXCEPTION)) {
4951 return Failure::Exception(); 5009 return Failure::Exception();
4952 } 5010 }
4953 5011
4954 return function->code(); 5012 return function->code();
4955 } 5013 }
4956 5014
4957 5015
4958 static Object* Runtime_GetCalledFunction(Arguments args) {
4959 HandleScope scope;
4960 ASSERT(args.length() == 0);
4961 StackFrameIterator it;
4962 // Get past the JS-to-C exit frame.
4963 ASSERT(it.frame()->is_exit());
4964 it.Advance();
4965 // Get past the CALL_NON_FUNCTION activation frame.
4966 ASSERT(it.frame()->is_java_script());
4967 it.Advance();
4968 // Argument adaptor frames do not copy the function; we have to skip
4969 // past them to get to the real calling frame.
4970 if (it.frame()->is_arguments_adaptor()) it.Advance();
4971 // Get the function from the top of the expression stack of the
4972 // calling frame.
4973 StandardFrame* frame = StandardFrame::cast(it.frame());
4974 int index = frame->ComputeExpressionsCount() - 1;
4975 Object* result = frame->GetExpression(index);
4976 return result;
4977 }
4978
4979
4980 static Object* Runtime_GetFunctionDelegate(Arguments args) { 5016 static Object* Runtime_GetFunctionDelegate(Arguments args) {
4981 HandleScope scope; 5017 HandleScope scope;
4982 ASSERT(args.length() == 1); 5018 ASSERT(args.length() == 1);
4983 RUNTIME_ASSERT(!args[0]->IsJSFunction()); 5019 RUNTIME_ASSERT(!args[0]->IsJSFunction());
4984 return *Execution::GetFunctionDelegate(args.at<Object>(0)); 5020 return *Execution::GetFunctionDelegate(args.at<Object>(0));
4985 } 5021 }
4986 5022
4987 5023
4988 static Object* Runtime_GetConstructorDelegate(Arguments args) { 5024 static Object* Runtime_GetConstructorDelegate(Arguments args) {
4989 HandleScope scope; 5025 HandleScope scope;
(...skipping 2984 matching lines...) Expand 10 before | Expand all | Expand 10 after
7974 CONVERT_CHECKED(JSFunction, f, args[0]); 8010 CONVERT_CHECKED(JSFunction, f, args[0]);
7975 return f->shared()->inferred_name(); 8011 return f->shared()->inferred_name();
7976 } 8012 }
7977 8013
7978 #endif // ENABLE_DEBUGGER_SUPPORT 8014 #endif // ENABLE_DEBUGGER_SUPPORT
7979 8015
7980 #ifdef ENABLE_LOGGING_AND_PROFILING 8016 #ifdef ENABLE_LOGGING_AND_PROFILING
7981 8017
7982 static Object* Runtime_ProfilerResume(Arguments args) { 8018 static Object* Runtime_ProfilerResume(Arguments args) {
7983 NoHandleAllocation ha; 8019 NoHandleAllocation ha;
7984 ASSERT(args.length() == 1); 8020 ASSERT(args.length() == 2);
7985 8021
7986 CONVERT_CHECKED(Smi, smi_modules, args[0]); 8022 CONVERT_CHECKED(Smi, smi_modules, args[0]);
7987 v8::V8::ResumeProfilerEx(smi_modules->value()); 8023 CONVERT_CHECKED(Smi, smi_tag, args[1]);
8024 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
7988 return Heap::undefined_value(); 8025 return Heap::undefined_value();
7989 } 8026 }
7990 8027
7991 8028
7992 static Object* Runtime_ProfilerPause(Arguments args) { 8029 static Object* Runtime_ProfilerPause(Arguments args) {
7993 NoHandleAllocation ha; 8030 NoHandleAllocation ha;
7994 ASSERT(args.length() == 1); 8031 ASSERT(args.length() == 2);
7995 8032
7996 CONVERT_CHECKED(Smi, smi_modules, args[0]); 8033 CONVERT_CHECKED(Smi, smi_modules, args[0]);
7997 v8::V8::PauseProfilerEx(smi_modules->value()); 8034 CONVERT_CHECKED(Smi, smi_tag, args[1]);
8035 v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
7998 return Heap::undefined_value(); 8036 return Heap::undefined_value();
7999 } 8037 }
8000 8038
8001 #endif // ENABLE_LOGGING_AND_PROFILING 8039 #endif // ENABLE_LOGGING_AND_PROFILING
8002 8040
8003 // Finds the script object from the script data. NOTE: This operation uses 8041 // Finds the script object from the script data. NOTE: This operation uses
8004 // heap traversal to find the function generated for the source position 8042 // heap traversal to find the function generated for the source position
8005 // for the requested break point. For lazily compiled functions several heap 8043 // for the requested break point. For lazily compiled functions several heap
8006 // traversals might be required rendering this operation as a rather slow 8044 // traversals might be required rendering this operation as a rather slow
8007 // operation. However for setting break points which is normally done through 8045 // operation. However for setting break points which is normally done through
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
8241 } else { 8279 } else {
8242 // Handle last resort GC and make sure to allow future allocations 8280 // Handle last resort GC and make sure to allow future allocations
8243 // to grow the heap without causing GCs (if possible). 8281 // to grow the heap without causing GCs (if possible).
8244 Counters::gc_last_resort_from_js.Increment(); 8282 Counters::gc_last_resort_from_js.Increment();
8245 Heap::CollectAllGarbage(false); 8283 Heap::CollectAllGarbage(false);
8246 } 8284 }
8247 } 8285 }
8248 8286
8249 8287
8250 } } // namespace v8::internal 8288 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698