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

Side by Side Diff: src/runtime.cc

Issue 14892: Merge changes from bleeding_edge into experimental toiger branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years 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/v8threads.h » ('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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 } 1054 }
1055 private: 1055 private:
1056 int suffixes_[kBMMaxShift + 1]; 1056 int suffixes_[kBMMaxShift + 1];
1057 int good_suffix_shift_[kBMMaxShift + 1]; 1057 int good_suffix_shift_[kBMMaxShift + 1];
1058 int* biased_suffixes_; 1058 int* biased_suffixes_;
1059 int* biased_good_suffix_shift_; 1059 int* biased_good_suffix_shift_;
1060 DISALLOW_COPY_AND_ASSIGN(BMGoodSuffixBuffers); 1060 DISALLOW_COPY_AND_ASSIGN(BMGoodSuffixBuffers);
1061 }; 1061 };
1062 1062
1063 // buffers reused by BoyerMoore 1063 // buffers reused by BoyerMoore
1064 static int bad_char_occurence[kBMAlphabetSize]; 1064 static int bad_char_occurrence[kBMAlphabetSize];
1065 static BMGoodSuffixBuffers bmgs_buffers; 1065 static BMGoodSuffixBuffers bmgs_buffers;
1066 1066
1067 // Compute the bad-char table for Boyer-Moore in the static buffer. 1067 // Compute the bad-char table for Boyer-Moore in the static buffer.
1068 template <typename pchar> 1068 template <typename pchar>
1069 static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern, 1069 static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern,
1070 int start) { 1070 int start) {
1071 // Run forwards to populate bad_char_table, so that *last* instance 1071 // Run forwards to populate bad_char_table, so that *last* instance
1072 // of character equivalence class is the one registered. 1072 // of character equivalence class is the one registered.
1073 // Notice: Doesn't include the last character. 1073 // Notice: Doesn't include the last character.
1074 int table_size = (sizeof(pchar) == 1) ? String::kMaxAsciiCharCode + 1 1074 int table_size = (sizeof(pchar) == 1) ? String::kMaxAsciiCharCode + 1
1075 : kBMAlphabetSize; 1075 : kBMAlphabetSize;
1076 if (start == 0) { // All patterns less than kBMMaxShift in length. 1076 if (start == 0) { // All patterns less than kBMMaxShift in length.
1077 memset(bad_char_occurence, -1, table_size * sizeof(*bad_char_occurence)); 1077 memset(bad_char_occurrence, -1, table_size * sizeof(*bad_char_occurrence));
1078 } else { 1078 } else {
1079 for (int i = 0; i < table_size; i++) { 1079 for (int i = 0; i < table_size; i++) {
1080 bad_char_occurence[i] = start - 1; 1080 bad_char_occurrence[i] = start - 1;
1081 } 1081 }
1082 } 1082 }
1083 for (int i = start; i < pattern.length() - 1; i++) { 1083 for (int i = start; i < pattern.length() - 1; i++) {
1084 pchar c = pattern[i]; 1084 pchar c = pattern[i];
1085 int bucket = (sizeof(pchar) ==1) ? c : c % kBMAlphabetSize; 1085 int bucket = (sizeof(pchar) ==1) ? c : c % kBMAlphabetSize;
1086 bad_char_occurence[bucket] = i; 1086 bad_char_occurrence[bucket] = i;
1087 } 1087 }
1088 } 1088 }
1089 1089
1090 template <typename pchar> 1090 template <typename pchar>
1091 static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern, 1091 static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern,
1092 int start) { 1092 int start) {
1093 int m = pattern.length(); 1093 int m = pattern.length();
1094 int len = m - start; 1094 int len = m - start;
1095 // Compute Good Suffix tables. 1095 // Compute Good Suffix tables.
1096 bmgs_buffers.init(m); 1096 bmgs_buffers.init(m);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 bmgs_buffers.shift(i) = suffix - start; 1131 bmgs_buffers.shift(i) = suffix - start;
1132 } 1132 }
1133 if (i == suffix) { 1133 if (i == suffix) {
1134 suffix = bmgs_buffers.suffix(suffix); 1134 suffix = bmgs_buffers.suffix(suffix);
1135 } 1135 }
1136 } 1136 }
1137 } 1137 }
1138 } 1138 }
1139 1139
1140 template <typename schar, typename pchar> 1140 template <typename schar, typename pchar>
1141 static inline int CharOccurence(int char_code) { 1141 static inline int CharOccurrence(int char_code) {
1142 if (sizeof(schar) == 1) { 1142 if (sizeof(schar) == 1) {
1143 return bad_char_occurence[char_code]; 1143 return bad_char_occurrence[char_code];
1144 } 1144 }
1145 if (sizeof(pchar) == 1) { 1145 if (sizeof(pchar) == 1) {
1146 if (char_code > String::kMaxAsciiCharCode) { 1146 if (char_code > String::kMaxAsciiCharCode) {
1147 return -1; 1147 return -1;
1148 } 1148 }
1149 return bad_char_occurence[char_code]; 1149 return bad_char_occurrence[char_code];
1150 } 1150 }
1151 return bad_char_occurence[char_code % kBMAlphabetSize]; 1151 return bad_char_occurrence[char_code % kBMAlphabetSize];
1152 } 1152 }
1153 1153
1154 // Restricted simplified Boyer-Moore string matching. Restricts tables to a 1154 // Restricted simplified Boyer-Moore string matching.
1155 // suffix of long pattern strings and handles only equivalence classes 1155 // Uses only the bad-shift table of Boyer-Moore and only uses it
1156 // of the full alphabet. This allows us to ensure that tables take only 1156 // for the character compared to the last character of the needle.
1157 // a fixed amount of space.
1158 template <typename schar, typename pchar> 1157 template <typename schar, typename pchar>
1159 static int BoyerMooreSimplified(Vector<const schar> subject, 1158 static int BoyerMooreHorsepool(Vector<const schar> subject,
1160 Vector<const pchar> pattern, 1159 Vector<const pchar> pattern,
1161 int start_index, 1160 int start_index,
1162 bool* complete) { 1161 bool* complete) {
1163 int n = subject.length(); 1162 int n = subject.length();
1164 int m = pattern.length(); 1163 int m = pattern.length();
1165 // Only preprocess at most kBMMaxShift last characters of pattern. 1164 // Only preprocess at most kBMMaxShift last characters of pattern.
1166 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift; 1165 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
1167 1166
1168 BoyerMoorePopulateBadCharTable(pattern, start); 1167 BoyerMoorePopulateBadCharTable(pattern, start);
1169 1168
1170 int badness = -m; // How bad we are doing without a good-suffix table. 1169 int badness = -m; // How bad we are doing without a good-suffix table.
1171 int idx; // No matches found prior to this index. 1170 int idx; // No matches found prior to this index.
1172 pchar last_char = pattern[m - 1]; 1171 pchar last_char = pattern[m - 1];
1172 int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char);
1173 // Perform search 1173 // Perform search
1174 for (idx = start_index; idx <= n - m;) { 1174 for (idx = start_index; idx <= n - m;) {
1175 int j = m - 1; 1175 int j = m - 1;
1176 int c; 1176 int c;
1177 while (last_char != (c = subject[idx + j])) { 1177 while (last_char != (c = subject[idx + j])) {
1178 int bc_occ = CharOccurence<schar, pchar>(c); 1178 int bc_occ = CharOccurrence<schar, pchar>(c);
1179 int shift = j - bc_occ; 1179 int shift = j - bc_occ;
1180 idx += shift; 1180 idx += shift;
1181 badness += 1 - shift; // at most zero, so badness cannot increase. 1181 badness += 1 - shift; // at most zero, so badness cannot increase.
1182 if (idx > n - m) { 1182 if (idx > n - m) {
1183 *complete = true; 1183 *complete = true;
1184 return -1; 1184 return -1;
1185 } 1185 }
1186 } 1186 }
1187 j--; 1187 j--;
1188 while (j >= 0 && pattern[j] == (c = subject[idx + j])) j--; 1188 while (j >= 0 && pattern[j] == (subject[idx + j])) j--;
1189 if (j < 0) { 1189 if (j < 0) {
1190 *complete = true; 1190 *complete = true;
1191 return idx; 1191 return idx;
1192 } else { 1192 } else {
1193 int bc_occ = CharOccurence<schar, pchar>(c); 1193 idx += last_char_shift;
1194 int shift = bc_occ < j ? j - bc_occ : 1;
1195 idx += shift;
1196 // Badness increases by the number of characters we have 1194 // Badness increases by the number of characters we have
1197 // checked, and decreases by the number of characters we 1195 // checked, and decreases by the number of characters we
1198 // can skip by shifting. It's a measure of how we are doing 1196 // can skip by shifting. It's a measure of how we are doing
1199 // compared to reading each character exactly once. 1197 // compared to reading each character exactly once.
1200 badness += (m - j) - shift; 1198 badness += (m - j) - last_char_shift;
1201 if (badness > 0) { 1199 if (badness > 0) {
1202 *complete = false; 1200 *complete = false;
1203 return idx; 1201 return idx;
1204 } 1202 }
1205 } 1203 }
1206 } 1204 }
1207 *complete = true; 1205 *complete = true;
1208 return -1; 1206 return -1;
1209 } 1207 }
1210 1208
1211 1209
1212 template <typename schar, typename pchar> 1210 template <typename schar, typename pchar>
1213 static int BoyerMooreIndexOf(Vector<const schar> subject, 1211 static int BoyerMooreIndexOf(Vector<const schar> subject,
1214 Vector<const pchar> pattern, 1212 Vector<const pchar> pattern,
1215 int idx) { 1213 int idx) {
1216 int n = subject.length(); 1214 int n = subject.length();
1217 int m = pattern.length(); 1215 int m = pattern.length();
1218 // Only preprocess at most kBMMaxShift last characters of pattern. 1216 // Only preprocess at most kBMMaxShift last characters of pattern.
1219 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift; 1217 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
1220 1218
1221 // Build the Good Suffix table and continue searching. 1219 // Build the Good Suffix table and continue searching.
1222 BoyerMoorePopulateGoodSuffixTable(pattern, start); 1220 BoyerMoorePopulateGoodSuffixTable(pattern, start);
1223 pchar last_char = pattern[m - 1]; 1221 pchar last_char = pattern[m - 1];
1224 // Continue search from i. 1222 // Continue search from i.
1225 do { 1223 do {
1226 int j = m - 1; 1224 int j = m - 1;
1227 schar c; 1225 schar c;
1228 while (last_char != (c = subject[idx + j])) { 1226 while (last_char != (c = subject[idx + j])) {
1229 int shift = j - CharOccurence<schar, pchar>(c); 1227 int shift = j - CharOccurrence<schar, pchar>(c);
1230 idx += shift; 1228 idx += shift;
1231 if (idx > n - m) { 1229 if (idx > n - m) {
1232 return -1; 1230 return -1;
1233 } 1231 }
1234 } 1232 }
1235 while (j >= 0 && pattern[j] == (c = subject[idx + j])) j--; 1233 while (j >= 0 && pattern[j] == (c = subject[idx + j])) j--;
1236 if (j < 0) { 1234 if (j < 0) {
1237 return idx; 1235 return idx;
1238 } else if (j < start) { 1236 } else if (j < start) {
1239 // we have matched more than our tables allow us to be smart about. 1237 // we have matched more than our tables allow us to be smart about.
1240 idx += 1; 1238 // Fall back on BMH shift.
1239 idx += m - 1 - CharOccurrence<schar, pchar>(last_char);
1241 } else { 1240 } else {
1242 int gs_shift = bmgs_buffers.shift(j + 1); // Good suffix shift. 1241 int gs_shift = bmgs_buffers.shift(j + 1); // Good suffix shift.
1243 int bc_occ = CharOccurence<schar, pchar>(c); 1242 int bc_occ = CharOccurrence<schar, pchar>(c);
1244 int shift = j - bc_occ; // Bad-char shift. 1243 int shift = j - bc_occ; // Bad-char shift.
1245 shift = (gs_shift > shift) ? gs_shift : shift; 1244 if (gs_shift > shift) {
1245 shift = gs_shift;
1246 }
1246 idx += shift; 1247 idx += shift;
1247 } 1248 }
1248 } while (idx <= n - m); 1249 } while (idx <= n - m);
1249 1250
1250 return -1; 1251 return -1;
1251 } 1252 }
1252 1253
1253 1254
1254 template <typename schar> 1255 template <typename schar>
1255 static int SingleCharIndexOf(Vector<const schar> string, 1256 static int SingleCharIndexOf(Vector<const schar> string,
(...skipping 23 matching lines...) Expand all
1279 // algorithm. 1280 // algorithm.
1280 int badness = -10 - (pattern.length() << 2); 1281 int badness = -10 - (pattern.length() << 2);
1281 // We know our pattern is at least 2 characters, we cache the first so 1282 // We know our pattern is at least 2 characters, we cache the first so
1282 // the common case of the first character not matching is faster. 1283 // the common case of the first character not matching is faster.
1283 pchar pattern_first_char = pattern[0]; 1284 pchar pattern_first_char = pattern[0];
1284 1285
1285 for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) { 1286 for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) {
1286 badness++; 1287 badness++;
1287 if (badness > 0) { 1288 if (badness > 0) {
1288 *complete = false; 1289 *complete = false;
1289 return (i); 1290 return i;
1290 } 1291 }
1291 if (subject[i] != pattern_first_char) continue; 1292 if (subject[i] != pattern_first_char) continue;
1292 int j = 1; 1293 int j = 1;
1293 do { 1294 do {
1294 if (pattern[j] != subject[i+j]) { 1295 if (pattern[j] != subject[i+j]) {
1295 break; 1296 break;
1296 } 1297 }
1297 j++; 1298 j++;
1298 } while (j < pattern.length()); 1299 } while (j < pattern.length());
1299 if (j == pattern.length()) { 1300 if (j == pattern.length()) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 if (pat.length() < kBMMinPatternLength) { 1351 if (pat.length() < kBMMinPatternLength) {
1351 // We don't believe fancy searching can ever be more efficient. 1352 // We don't believe fancy searching can ever be more efficient.
1352 // The max shift of Boyer-Moore on a pattern of this length does 1353 // The max shift of Boyer-Moore on a pattern of this length does
1353 // not compensate for the overhead. 1354 // not compensate for the overhead.
1354 return SimpleIndexOf(sub, pat, start_index); 1355 return SimpleIndexOf(sub, pat, start_index);
1355 } 1356 }
1356 // Try algorithms in order of increasing setup cost and expected performance. 1357 // Try algorithms in order of increasing setup cost and expected performance.
1357 bool complete; 1358 bool complete;
1358 int idx = SimpleIndexOf(sub, pat, start_index, &complete); 1359 int idx = SimpleIndexOf(sub, pat, start_index, &complete);
1359 if (complete) return idx; 1360 if (complete) return idx;
1360 idx = BoyerMooreSimplified(sub, pat, idx, &complete); 1361 idx = BoyerMooreHorsepool(sub, pat, idx, &complete);
1361 if (complete) return idx; 1362 if (complete) return idx;
1362 return BoyerMooreIndexOf(sub, pat, idx); 1363 return BoyerMooreIndexOf(sub, pat, idx);
1363 } 1364 }
1364 1365
1365 // Perform string match of pattern on subject, starting at start index. 1366 // Perform string match of pattern on subject, starting at start index.
1366 // Caller must ensure that 0 <= start_index <= sub->length(), 1367 // Caller must ensure that 0 <= start_index <= sub->length(),
1367 // and should check that pat->length() + start_index <= sub->length() 1368 // and should check that pat->length() + start_index <= sub->length()
1368 int Runtime::StringMatch(Handle<String> sub, 1369 int Runtime::StringMatch(Handle<String> sub,
1369 Handle<String> pat, 1370 Handle<String> pat,
1370 int start_index) { 1371 int start_index) {
(...skipping 1944 matching lines...) Expand 10 before | Expand all | Expand 10 after
3315 3316
3316 3317
3317 static Object* Runtime_NewObject(Arguments args) { 3318 static Object* Runtime_NewObject(Arguments args) {
3318 NoHandleAllocation ha; 3319 NoHandleAllocation ha;
3319 ASSERT(args.length() == 1); 3320 ASSERT(args.length() == 1);
3320 3321
3321 Object* constructor = args[0]; 3322 Object* constructor = args[0];
3322 if (constructor->IsJSFunction()) { 3323 if (constructor->IsJSFunction()) {
3323 JSFunction* function = JSFunction::cast(constructor); 3324 JSFunction* function = JSFunction::cast(constructor);
3324 3325
3325 // Handle steping into constructors. 3326 // Handle steping into constructors if step into is active.
3326 if (Debug::StepInActive()) { 3327 if (Debug::StepInActive()) {
3327 StackFrameIterator it; 3328 HandleScope scope;
3328 it.Advance(); 3329 Debug::HandleStepIn(Handle<JSFunction>(function), 0, true);
3329 ASSERT(it.frame()->is_construct());
3330 it.Advance();
3331 if (it.frame()->fp() == Debug::step_in_fp()) {
3332 HandleScope scope;
3333 Debug::FloodWithOneShot(Handle<SharedFunctionInfo>(function->shared()));
3334 }
3335 } 3330 }
3336 3331
3337 if (function->has_initial_map() && 3332 if (function->has_initial_map() &&
3338 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { 3333 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
3339 // The 'Function' function ignores the receiver object when 3334 // The 'Function' function ignores the receiver object when
3340 // called using 'new' and creates a new JSFunction object that 3335 // called using 'new' and creates a new JSFunction object that
3341 // is returned. The receiver object is only used for error 3336 // is returned. The receiver object is only used for error
3342 // reporting if an error occurs when constructing the new 3337 // reporting if an error occurs when constructing the new
3343 // JSFunction. AllocateJSObject should not be used to allocate 3338 // JSFunction. AllocateJSObject should not be used to allocate
3344 // JSFunctions since it does not properly initialize the shared 3339 // JSFunctions since it does not properly initialize the shared
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3420 CONVERT_CHECKED(JSFunction, function, args[0]); 3415 CONVERT_CHECKED(JSFunction, function, args[0]);
3421 int length = ScopeInfo<>::NumberOfContextSlots(function->code()); 3416 int length = ScopeInfo<>::NumberOfContextSlots(function->code());
3422 Object* result = Heap::AllocateFunctionContext(length, function); 3417 Object* result = Heap::AllocateFunctionContext(length, function);
3423 if (result->IsFailure()) return result; 3418 if (result->IsFailure()) return result;
3424 3419
3425 Top::set_context(Context::cast(result)); 3420 Top::set_context(Context::cast(result));
3426 3421
3427 return result; // non-failure 3422 return result; // non-failure
3428 } 3423 }
3429 3424
3430 3425 static Object* PushContextHelper(Object* object, bool is_catch_context) {
3431 static Object* Runtime_PushContext(Arguments args) {
3432 NoHandleAllocation ha;
3433 ASSERT(args.length() == 1);
3434
3435 // Convert the object to a proper JavaScript object. 3426 // Convert the object to a proper JavaScript object.
3436 Object* object = args[0]; 3427 Object* js_object = object;
3437 if (!object->IsJSObject()) { 3428 if (!js_object->IsJSObject()) {
3438 object = object->ToObject(); 3429 js_object = js_object->ToObject();
3439 if (object->IsFailure()) { 3430 if (js_object->IsFailure()) {
3440 if (!Failure::cast(object)->IsInternalError()) return object; 3431 if (!Failure::cast(js_object)->IsInternalError()) return js_object;
3441 HandleScope scope; 3432 HandleScope scope;
3442 Handle<Object> handle(args[0]); 3433 Handle<Object> handle(object);
3443 Handle<Object> result = 3434 Handle<Object> result =
3444 Factory::NewTypeError("with_expression", HandleVector(&handle, 1)); 3435 Factory::NewTypeError("with_expression", HandleVector(&handle, 1));
3445 return Top::Throw(*result); 3436 return Top::Throw(*result);
3446 } 3437 }
3447 } 3438 }
3448 3439
3449 Object* result = 3440 Object* result =
3450 Heap::AllocateWithContext(Top::context(), JSObject::cast(object)); 3441 Heap::AllocateWithContext(Top::context(),
3442 JSObject::cast(js_object),
3443 is_catch_context);
3451 if (result->IsFailure()) return result; 3444 if (result->IsFailure()) return result;
3452 3445
3453 Top::set_context(Context::cast(result)); 3446 Context* context = Context::cast(result);
3447 Top::set_context(context);
3454 3448
3455 return result; 3449 return result;
3456 } 3450 }
3457 3451
3458 3452
3453 static Object* Runtime_PushContext(Arguments args) {
3454 NoHandleAllocation ha;
3455 ASSERT(args.length() == 1);
3456 return PushContextHelper(args[0], false);
3457 }
3458
3459
3460 static Object* Runtime_PushCatchContext(Arguments args) {
3461 NoHandleAllocation ha;
3462 ASSERT(args.length() == 1);
3463 return PushContextHelper(args[0], true);
3464 }
3465
3466
3459 static Object* Runtime_LookupContext(Arguments args) { 3467 static Object* Runtime_LookupContext(Arguments args) {
3460 HandleScope scope; 3468 HandleScope scope;
3461 ASSERT(args.length() == 2); 3469 ASSERT(args.length() == 2);
3462 3470
3463 CONVERT_ARG_CHECKED(Context, context, 0); 3471 CONVERT_ARG_CHECKED(Context, context, 0);
3464 CONVERT_ARG_CHECKED(String, name, 1); 3472 CONVERT_ARG_CHECKED(String, name, 1);
3465 3473
3466 int index; 3474 int index;
3467 PropertyAttributes attributes; 3475 PropertyAttributes attributes;
3468 ContextLookupFlags flags = FOLLOW_CHAINS; 3476 ContextLookupFlags flags = FOLLOW_CHAINS;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3546 Object* value = (holder->IsContext()) 3554 Object* value = (holder->IsContext())
3547 ? Context::cast(*holder)->get(index) 3555 ? Context::cast(*holder)->get(index)
3548 : JSObject::cast(*holder)->GetElement(index); 3556 : JSObject::cast(*holder)->GetElement(index);
3549 return MakePair(Unhole(value, attributes), receiver); 3557 return MakePair(Unhole(value, attributes), receiver);
3550 } 3558 }
3551 3559
3552 // If the holder is found, we read the property from it. 3560 // If the holder is found, we read the property from it.
3553 if (!holder.is_null() && holder->IsJSObject()) { 3561 if (!holder.is_null() && holder->IsJSObject()) {
3554 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name)); 3562 ASSERT(Handle<JSObject>::cast(holder)->HasProperty(*name));
3555 JSObject* object = JSObject::cast(*holder); 3563 JSObject* object = JSObject::cast(*holder);
3556 JSObject* receiver = (object->IsGlobalObject()) 3564 JSObject* receiver;
3557 ? GlobalObject::cast(object)->global_receiver() 3565 if (object->IsGlobalObject()) {
3558 : ComputeReceiverForNonGlobal(object); 3566 receiver = GlobalObject::cast(object)->global_receiver();
3567 } else if (context->is_exception_holder(*holder)) {
3568 receiver = Top::context()->global()->global_receiver();
3569 } else {
3570 receiver = ComputeReceiverForNonGlobal(object);
3571 }
3559 // No need to unhole the value here. This is taken care of by the 3572 // No need to unhole the value here. This is taken care of by the
3560 // GetProperty function. 3573 // GetProperty function.
3561 Object* value = object->GetProperty(*name); 3574 Object* value = object->GetProperty(*name);
3562 return MakePair(value, receiver); 3575 return MakePair(value, receiver);
3563 } 3576 }
3564 3577
3565 if (throw_error) { 3578 if (throw_error) {
3566 // The property doesn't exist - throw exception. 3579 // The property doesn't exist - throw exception.
3567 Handle<Object> reference_error = 3580 Handle<Object> reference_error =
3568 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); 3581 Factory::NewReferenceError("not_defined", HandleVector(&name, 1));
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after
5212 Handle<Context> function_context) { 5225 Handle<Context> function_context) {
5213 // At the bottom of the chain. Return the function context to link to. 5226 // At the bottom of the chain. Return the function context to link to.
5214 if (context_chain->is_function_context()) { 5227 if (context_chain->is_function_context()) {
5215 return function_context; 5228 return function_context;
5216 } 5229 }
5217 5230
5218 // Recursively copy the with contexts. 5231 // Recursively copy the with contexts.
5219 Handle<Context> previous(context_chain->previous()); 5232 Handle<Context> previous(context_chain->previous());
5220 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); 5233 Handle<JSObject> extension(JSObject::cast(context_chain->extension()));
5221 return Factory::NewWithContext( 5234 return Factory::NewWithContext(
5222 CopyWithContextChain(function_context, previous), extension); 5235 CopyWithContextChain(function_context, previous),
5236 extension,
5237 context_chain->IsCatchContext());
5223 } 5238 }
5224 5239
5225 5240
5226 // Helper function to find or create the arguments object for 5241 // Helper function to find or create the arguments object for
5227 // Runtime_DebugEvaluate. 5242 // Runtime_DebugEvaluate.
5228 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame, 5243 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame,
5229 Handle<JSFunction> function, 5244 Handle<JSFunction> function,
5230 Handle<Code> code, 5245 Handle<Code> code,
5231 const ScopeInfo<>* sinfo, 5246 const ScopeInfo<>* sinfo,
5232 Handle<Context> function_context) { 5247 Handle<Context> function_context) {
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
5871 } else { 5886 } else {
5872 // Handle last resort GC and make sure to allow future allocations 5887 // Handle last resort GC and make sure to allow future allocations
5873 // to grow the heap without causing GCs (if possible). 5888 // to grow the heap without causing GCs (if possible).
5874 Counters::gc_last_resort_from_js.Increment(); 5889 Counters::gc_last_resort_from_js.Increment();
5875 Heap::CollectAllGarbage(); 5890 Heap::CollectAllGarbage();
5876 } 5891 }
5877 } 5892 }
5878 5893
5879 5894
5880 } } // namespace v8::internal 5895 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/v8threads.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698