deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / test / cctest / test-compiler.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <stdlib.h>
29 #include <wchar.h>
30
31 #include "src/v8.h"
32
33 #include "src/compiler.h"
34 #include "src/disasm.h"
35 #include "src/parser.h"
36 #include "test/cctest/cctest.h"
37
38 using namespace v8::internal;
39
40 static Handle<Object> GetGlobalProperty(const char* name) {
41   Isolate* isolate = CcTest::i_isolate();
42   return Object::GetProperty(
43       isolate, isolate->global_object(), name).ToHandleChecked();
44 }
45
46
47 static void SetGlobalProperty(const char* name, Object* value) {
48   Isolate* isolate = CcTest::i_isolate();
49   Handle<Object> object(value, isolate);
50   Handle<String> internalized_name =
51       isolate->factory()->InternalizeUtf8String(name);
52   Handle<JSObject> global(isolate->context()->global_object());
53   Runtime::SetObjectProperty(isolate, global, internalized_name, object,
54                              SLOPPY).Check();
55 }
56
57
58 static Handle<JSFunction> Compile(const char* source) {
59   Isolate* isolate = CcTest::i_isolate();
60   Handle<String> source_code = isolate->factory()->NewStringFromUtf8(
61       CStrVector(source)).ToHandleChecked();
62   Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
63       source_code, Handle<String>(), 0, 0, false, false, Handle<Object>(),
64       Handle<Context>(isolate->native_context()), NULL, NULL,
65       v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
66   return isolate->factory()->NewFunctionFromSharedFunctionInfo(
67       shared_function, isolate->native_context());
68 }
69
70
71 static double Inc(Isolate* isolate, int x) {
72   const char* source = "result = %d + 1;";
73   EmbeddedVector<char, 512> buffer;
74   SNPrintF(buffer, source, x);
75
76   Handle<JSFunction> fun = Compile(buffer.start());
77   if (fun.is_null()) return -1;
78
79   Handle<JSObject> global(isolate->context()->global_object());
80   Execution::Call(isolate, fun, global, 0, NULL).Check();
81   return GetGlobalProperty("result")->Number();
82 }
83
84
85 TEST(Inc) {
86   CcTest::InitializeVM();
87   v8::HandleScope scope(CcTest::isolate());
88   CHECK_EQ(4.0, Inc(CcTest::i_isolate(), 3));
89 }
90
91
92 static double Add(Isolate* isolate, int x, int y) {
93   Handle<JSFunction> fun = Compile("result = x + y;");
94   if (fun.is_null()) return -1;
95
96   SetGlobalProperty("x", Smi::FromInt(x));
97   SetGlobalProperty("y", Smi::FromInt(y));
98   Handle<JSObject> global(isolate->context()->global_object());
99   Execution::Call(isolate, fun, global, 0, NULL).Check();
100   return GetGlobalProperty("result")->Number();
101 }
102
103
104 TEST(Add) {
105   CcTest::InitializeVM();
106   v8::HandleScope scope(CcTest::isolate());
107   CHECK_EQ(5.0, Add(CcTest::i_isolate(), 2, 3));
108 }
109
110
111 static double Abs(Isolate* isolate, int x) {
112   Handle<JSFunction> fun = Compile("if (x < 0) result = -x; else result = x;");
113   if (fun.is_null()) return -1;
114
115   SetGlobalProperty("x", Smi::FromInt(x));
116   Handle<JSObject> global(isolate->context()->global_object());
117   Execution::Call(isolate, fun, global, 0, NULL).Check();
118   return GetGlobalProperty("result")->Number();
119 }
120
121
122 TEST(Abs) {
123   CcTest::InitializeVM();
124   v8::HandleScope scope(CcTest::isolate());
125   CHECK_EQ(3.0, Abs(CcTest::i_isolate(), -3));
126 }
127
128
129 static double Sum(Isolate* isolate, int n) {
130   Handle<JSFunction> fun =
131       Compile("s = 0; while (n > 0) { s += n; n -= 1; }; result = s;");
132   if (fun.is_null()) return -1;
133
134   SetGlobalProperty("n", Smi::FromInt(n));
135   Handle<JSObject> global(isolate->context()->global_object());
136   Execution::Call(isolate, fun, global, 0, NULL).Check();
137   return GetGlobalProperty("result")->Number();
138 }
139
140
141 TEST(Sum) {
142   CcTest::InitializeVM();
143   v8::HandleScope scope(CcTest::isolate());
144   CHECK_EQ(5050.0, Sum(CcTest::i_isolate(), 100));
145 }
146
147
148 TEST(Print) {
149   v8::HandleScope scope(CcTest::isolate());
150   v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION);
151   v8::Context::Scope context_scope(context);
152   const char* source = "for (n = 0; n < 100; ++n) print(n, 1, 2);";
153   Handle<JSFunction> fun = Compile(source);
154   if (fun.is_null()) return;
155   Handle<JSObject> global(CcTest::i_isolate()->context()->global_object());
156   Execution::Call(CcTest::i_isolate(), fun, global, 0, NULL).Check();
157 }
158
159
160 // The following test method stems from my coding efforts today. It
161 // tests all the functionality I have added to the compiler today
162 TEST(Stuff) {
163   CcTest::InitializeVM();
164   v8::HandleScope scope(CcTest::isolate());
165   const char* source =
166     "r = 0;\n"
167     "a = new Object;\n"
168     "if (a == a) r+=1;\n"  // 1
169     "if (a != new Object()) r+=2;\n"  // 2
170     "a.x = 42;\n"
171     "if (a.x == 42) r+=4;\n"  // 4
172     "function foo() { var x = 87; return x; }\n"
173     "if (foo() == 87) r+=8;\n"  // 8
174     "function bar() { var x; x = 99; return x; }\n"
175     "if (bar() == 99) r+=16;\n"  // 16
176     "function baz() { var x = 1, y, z = 2; y = 3; return x + y + z; }\n"
177     "if (baz() == 6) r+=32;\n"  // 32
178     "function Cons0() { this.x = 42; this.y = 87; }\n"
179     "if (new Cons0().x == 42) r+=64;\n"  // 64
180     "if (new Cons0().y == 87) r+=128;\n"  // 128
181     "function Cons2(x, y) { this.sum = x + y; }\n"
182     "if (new Cons2(3,4).sum == 7) r+=256;";  // 256
183
184   Handle<JSFunction> fun = Compile(source);
185   CHECK(!fun.is_null());
186   Handle<JSObject> global(CcTest::i_isolate()->context()->global_object());
187   Execution::Call(
188       CcTest::i_isolate(), fun, global, 0, NULL).Check();
189   CHECK_EQ(511.0, GetGlobalProperty("r")->Number());
190 }
191
192
193 TEST(UncaughtThrow) {
194   CcTest::InitializeVM();
195   v8::HandleScope scope(CcTest::isolate());
196
197   const char* source = "throw 42;";
198   Handle<JSFunction> fun = Compile(source);
199   CHECK(!fun.is_null());
200   Isolate* isolate = fun->GetIsolate();
201   Handle<JSObject> global(isolate->context()->global_object());
202   CHECK(Execution::Call(isolate, fun, global, 0, NULL).is_null());
203   CHECK_EQ(42.0, isolate->pending_exception()->Number());
204 }
205
206
207 // Tests calling a builtin function from C/C++ code, and the builtin function
208 // performs GC. It creates a stack frame looks like following:
209 //   | C (PerformGC) |
210 //   |   JS-to-C     |
211 //   |      JS       |
212 //   |   C-to-JS     |
213 TEST(C2JSFrames) {
214   FLAG_expose_gc = true;
215   v8::HandleScope scope(CcTest::isolate());
216   v8::Local<v8::Context> context =
217     CcTest::NewContext(PRINT_EXTENSION | GC_EXTENSION);
218   v8::Context::Scope context_scope(context);
219
220   const char* source = "function foo(a) { gc(), print(a); }";
221
222   Handle<JSFunction> fun0 = Compile(source);
223   CHECK(!fun0.is_null());
224   Isolate* isolate = fun0->GetIsolate();
225
226   // Run the generated code to populate the global object with 'foo'.
227   Handle<JSObject> global(isolate->context()->global_object());
228   Execution::Call(isolate, fun0, global, 0, NULL).Check();
229
230   Handle<String> foo_string =
231       isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("foo"));
232   Handle<Object> fun1 = Object::GetProperty(
233       isolate->global_object(), foo_string).ToHandleChecked();
234   CHECK(fun1->IsJSFunction());
235
236   Handle<Object> argv[] = {isolate->factory()->InternalizeOneByteString(
237       STATIC_CHAR_VECTOR("hello"))};
238   Execution::Call(isolate,
239                   Handle<JSFunction>::cast(fun1),
240                   global,
241                   arraysize(argv),
242                   argv).Check();
243 }
244
245
246 // Regression 236. Calling InitLineEnds on a Script with undefined
247 // source resulted in crash.
248 TEST(Regression236) {
249   CcTest::InitializeVM();
250   Isolate* isolate = CcTest::i_isolate();
251   Factory* factory = isolate->factory();
252   v8::HandleScope scope(CcTest::isolate());
253
254   Handle<Script> script = factory->NewScript(factory->empty_string());
255   script->set_source(CcTest::heap()->undefined_value());
256   CHECK_EQ(-1, Script::GetLineNumber(script, 0));
257   CHECK_EQ(-1, Script::GetLineNumber(script, 100));
258   CHECK_EQ(-1, Script::GetLineNumber(script, -1));
259 }
260
261
262 TEST(GetScriptLineNumber) {
263   LocalContext context;
264   v8::HandleScope scope(CcTest::isolate());
265   v8::ScriptOrigin origin =
266       v8::ScriptOrigin(v8::String::NewFromUtf8(CcTest::isolate(), "test"));
267   const char function_f[] = "function f() {}";
268   const int max_rows = 1000;
269   const int buffer_size = max_rows + sizeof(function_f);
270   ScopedVector<char> buffer(buffer_size);
271   memset(buffer.start(), '\n', buffer_size - 1);
272   buffer[buffer_size - 1] = '\0';
273
274   for (int i = 0; i < max_rows; ++i) {
275     if (i > 0)
276       buffer[i - 1] = '\n';
277     MemCopy(&buffer[i], function_f, sizeof(function_f) - 1);
278     v8::Handle<v8::String> script_body =
279         v8::String::NewFromUtf8(CcTest::isolate(), buffer.start());
280     v8::Script::Compile(script_body, &origin)->Run();
281     v8::Local<v8::Function> f =
282         v8::Local<v8::Function>::Cast(context->Global()->Get(
283             v8::String::NewFromUtf8(CcTest::isolate(), "f")));
284     CHECK_EQ(i, f->GetScriptLineNumber());
285   }
286 }
287
288
289 TEST(FeedbackVectorPreservedAcrossRecompiles) {
290   if (i::FLAG_always_opt || !i::FLAG_crankshaft) return;
291   i::FLAG_allow_natives_syntax = true;
292   CcTest::InitializeVM();
293   if (!CcTest::i_isolate()->use_crankshaft()) return;
294   v8::HandleScope scope(CcTest::isolate());
295
296   // Make sure function f has a call that uses a type feedback slot.
297   CompileRun("function fun() {};"
298              "fun1 = fun;"
299              "function f(a) { a(); } f(fun1);");
300
301   Handle<JSFunction> f =
302       v8::Utils::OpenHandle(
303           *v8::Handle<v8::Function>::Cast(
304               CcTest::global()->Get(v8_str("f"))));
305
306   // We shouldn't have deoptimization support. We want to recompile and
307   // verify that our feedback vector preserves information.
308   CHECK(!f->shared()->has_deoptimization_support());
309   Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
310
311   // Verify that we gathered feedback.
312   int expected_slots = 0;
313   int expected_ic_slots = 1;
314   CHECK_EQ(expected_slots, feedback_vector->Slots());
315   CHECK_EQ(expected_ic_slots, feedback_vector->ICSlots());
316   FeedbackVectorICSlot slot_for_a(0);
317   Object* object = feedback_vector->Get(slot_for_a);
318   CHECK(object->IsWeakCell() &&
319         WeakCell::cast(object)->value()->IsJSFunction());
320
321   CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);");
322
323   // Verify that the feedback is still "gathered" despite a recompilation
324   // of the full code.
325   CHECK(f->IsOptimized());
326   CHECK(f->shared()->has_deoptimization_support());
327   object = f->shared()->feedback_vector()->Get(slot_for_a);
328   CHECK(object->IsWeakCell() &&
329         WeakCell::cast(object)->value()->IsJSFunction());
330 }
331
332
333 TEST(FeedbackVectorUnaffectedByScopeChanges) {
334   if (i::FLAG_always_opt || !i::FLAG_lazy) return;
335   CcTest::InitializeVM();
336   v8::HandleScope scope(CcTest::isolate());
337
338   CompileRun("function builder() {"
339              "  call_target = function() { return 3; };"
340              "  return (function() {"
341              "    eval('');"
342              "    return function() {"
343              "      'use strict';"
344              "      call_target();"
345              "    }"
346              "  })();"
347              "}"
348              "morphing_call = builder();");
349
350   Handle<JSFunction> f =
351       v8::Utils::OpenHandle(
352           *v8::Handle<v8::Function>::Cast(
353               CcTest::global()->Get(v8_str("morphing_call"))));
354
355   // Not compiled, and so no feedback vector allocated yet.
356   CHECK(!f->shared()->is_compiled());
357   CHECK_EQ(0, f->shared()->feedback_vector()->Slots());
358   CHECK_EQ(0, f->shared()->feedback_vector()->ICSlots());
359
360   CompileRun("morphing_call();");
361
362   // Now a feedback vector is allocated.
363   CHECK(f->shared()->is_compiled());
364   int expected_slots = 0;
365   int expected_ic_slots = FLAG_vector_ics ? 2 : 1;
366   CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
367   CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
368 }
369
370
371 // Test that optimized code for different closures is actually shared
372 // immediately by the FastNewClosureStub when run in the same context.
373 TEST(OptimizedCodeSharing) {
374   // Skip test if --cache-optimized-code is not activated by default because
375   // FastNewClosureStub that is baked into the snapshot is incorrect.
376   if (!FLAG_cache_optimized_code) return;
377   FLAG_stress_compaction = false;
378   FLAG_allow_natives_syntax = true;
379   CcTest::InitializeVM();
380   v8::HandleScope scope(CcTest::isolate());
381   for (int i = 0; i < 10; i++) {
382     LocalContext env;
383     env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
384                        v8::Integer::New(CcTest::isolate(), i));
385     CompileRun("function MakeClosure() {"
386                "  return function() { return x; };"
387                "}"
388                "var closure0 = MakeClosure();"
389                "%DebugPrint(closure0());"
390                "%OptimizeFunctionOnNextCall(closure0);"
391                "%DebugPrint(closure0());"
392                "var closure1 = MakeClosure();"
393                "var closure2 = MakeClosure();");
394     Handle<JSFunction> fun1 = v8::Utils::OpenHandle(
395         *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1"))));
396     Handle<JSFunction> fun2 = v8::Utils::OpenHandle(
397         *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2"))));
398     CHECK(fun1->IsOptimized()
399           || !CcTest::i_isolate()->use_crankshaft() || !fun1->IsOptimizable());
400     CHECK(fun2->IsOptimized()
401           || !CcTest::i_isolate()->use_crankshaft() || !fun2->IsOptimizable());
402     CHECK_EQ(fun1->code(), fun2->code());
403   }
404 }
405
406
407 TEST(CompileFunctionInContext) {
408   CcTest::InitializeVM();
409   v8::HandleScope scope(CcTest::isolate());
410   LocalContext env;
411   CompileRun("var r = 10;");
412   v8::Local<v8::Object> math =
413       v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("Math")));
414   v8::ScriptCompiler::Source script_source(v8_str(
415       "a = PI * r * r;"
416       "x = r * cos(PI);"
417       "y = r * sin(PI / 2);"));
418   v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
419       CcTest::isolate(), &script_source, env.local(), 0, NULL, 1, &math);
420   CHECK(!fun.IsEmpty());
421   fun->Call(env->Global(), 0, NULL);
422   CHECK(env->Global()->Has(v8_str("a")));
423   v8::Local<v8::Value> a = env->Global()->Get(v8_str("a"));
424   CHECK(a->IsNumber());
425   CHECK(env->Global()->Has(v8_str("x")));
426   v8::Local<v8::Value> x = env->Global()->Get(v8_str("x"));
427   CHECK(x->IsNumber());
428   CHECK(env->Global()->Has(v8_str("y")));
429   v8::Local<v8::Value> y = env->Global()->Get(v8_str("y"));
430   CHECK(y->IsNumber());
431   CHECK_EQ(314.1592653589793, a->NumberValue());
432   CHECK_EQ(-10.0, x->NumberValue());
433   CHECK_EQ(10.0, y->NumberValue());
434 }
435
436
437 TEST(CompileFunctionInContextComplex) {
438   CcTest::InitializeVM();
439   v8::HandleScope scope(CcTest::isolate());
440   LocalContext env;
441   CompileRun(
442       "var x = 1;"
443       "var y = 2;"
444       "var z = 4;"
445       "var a = {x: 8, y: 16};"
446       "var b = {x: 32};");
447   v8::Local<v8::Object> ext[2];
448   ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
449   ext[1] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("b")));
450   v8::ScriptCompiler::Source script_source(v8_str("result = x + y + z"));
451   v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
452       CcTest::isolate(), &script_source, env.local(), 0, NULL, 2, ext);
453   CHECK(!fun.IsEmpty());
454   fun->Call(env->Global(), 0, NULL);
455   CHECK(env->Global()->Has(v8_str("result")));
456   v8::Local<v8::Value> result = env->Global()->Get(v8_str("result"));
457   CHECK(result->IsNumber());
458   CHECK_EQ(52.0, result->NumberValue());
459 }
460
461
462 TEST(CompileFunctionInContextArgs) {
463   CcTest::InitializeVM();
464   v8::HandleScope scope(CcTest::isolate());
465   LocalContext env;
466   CompileRun("var a = {x: 23};");
467   v8::Local<v8::Object> ext[1];
468   ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
469   v8::ScriptCompiler::Source script_source(v8_str("result = x + b"));
470   v8::Local<v8::String> arg = v8_str("b");
471   v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
472       CcTest::isolate(), &script_source, env.local(), 1, &arg, 1, ext);
473   CHECK(!fun.IsEmpty());
474   v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0);
475   fun->Call(env->Global(), 1, &b_value);
476   CHECK(env->Global()->Has(v8_str("result")));
477   v8::Local<v8::Value> result = env->Global()->Get(v8_str("result"));
478   CHECK(result->IsNumber());
479   CHECK_EQ(65.0, result->NumberValue());
480 }
481
482
483 TEST(CompileFunctionInContextComments) {
484   CcTest::InitializeVM();
485   v8::HandleScope scope(CcTest::isolate());
486   LocalContext env;
487   CompileRun("var a = {x: 23, y: 1, z: 2};");
488   v8::Local<v8::Object> ext[1];
489   ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
490   v8::ScriptCompiler::Source script_source(
491       v8_str("result = /* y + */ x + b // + z"));
492   v8::Local<v8::String> arg = v8_str("b");
493   v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
494       CcTest::isolate(), &script_source, env.local(), 1, &arg, 1, ext);
495   CHECK(!fun.IsEmpty());
496   v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0);
497   fun->Call(env->Global(), 1, &b_value);
498   CHECK(env->Global()->Has(v8_str("result")));
499   v8::Local<v8::Value> result = env->Global()->Get(v8_str("result"));
500   CHECK(result->IsNumber());
501   CHECK_EQ(65.0, result->NumberValue());
502 }
503
504
505 TEST(CompileFunctionInContextNonIdentifierArgs) {
506   CcTest::InitializeVM();
507   v8::HandleScope scope(CcTest::isolate());
508   LocalContext env;
509   v8::ScriptCompiler::Source script_source(v8_str("result = 1"));
510   v8::Local<v8::String> arg = v8_str("b }");
511   v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext(
512       CcTest::isolate(), &script_source, env.local(), 1, &arg, 0, NULL);
513   CHECK(fun.IsEmpty());
514 }
515
516
517 #ifdef ENABLE_DISASSEMBLER
518 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
519                                  const char* property_name) {
520   v8::Local<v8::Function> fun =
521       v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name)));
522   return v8::Utils::OpenHandle(*fun);
523 }
524
525
526 static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
527   // Create a disassembler with default name lookup.
528   disasm::NameConverter name_converter;
529   disasm::Disassembler d(name_converter);
530
531   if (f->code()->kind() == Code::FUNCTION) {
532     Address pc = f->code()->instruction_start();
533     int decode_size =
534         Min(f->code()->instruction_size(),
535             static_cast<int>(f->code()->back_edge_table_offset()));
536     Address end = pc + decode_size;
537
538     v8::internal::EmbeddedVector<char, 128> decode_buffer;
539     v8::internal::EmbeddedVector<char, 128> smi_hex_buffer;
540     Smi* smi = Smi::FromInt(12345678);
541     SNPrintF(smi_hex_buffer, "0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(smi));
542     while (pc < end) {
543       int num_const = d.ConstantPoolSizeAt(pc);
544       if (num_const >= 0) {
545         pc += (num_const + 1) * kPointerSize;
546       } else {
547         pc += d.InstructionDecode(decode_buffer, pc);
548         CHECK(strstr(decode_buffer.start(), smi_hex_buffer.start()) == NULL);
549       }
550     }
551   }
552 }
553
554
555 TEST(SplitConstantsInFullCompiler) {
556   LocalContext context;
557   v8::HandleScope scope(CcTest::isolate());
558
559   CompileRun("function f() { a = 12345678 }; f();");
560   CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
561   CompileRun("function f(x) { a = 12345678 + x}; f(1);");
562   CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
563   CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);");
564   CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
565   CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);");
566   CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
567 }
568 #endif