OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 * | 7 * |
8 */ | 8 */ |
9 #include "Global.h" | 9 #include "Global.h" |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 do { | 23 do { |
24 fLastTimerID++; | 24 fLastTimerID++; |
25 if (fLastTimerID < 0) { | 25 if (fLastTimerID < 0) { |
26 fLastTimerID = 0; | 26 fLastTimerID = 0; |
27 } | 27 } |
28 } while (fTimeouts.find(fLastTimerID) != fTimeouts.end()); | 28 } while (fTimeouts.find(fLastTimerID) != fTimeouts.end()); |
29 return fLastTimerID; | 29 return fLastTimerID; |
30 } | 30 } |
31 | 31 |
32 // Slight modification to an original function found in the V8 sample shell.cc. | 32 // Slight modification to an original function found in the V8 sample shell.cc. |
33 void Global::reportException(TryCatch* tryCatch) { | 33 void Global::reportException(v8::TryCatch* tryCatch) { |
34 HandleScope handleScope(fIsolate); | 34 v8::HandleScope handleScope(fIsolate); |
35 String::Utf8Value exception(tryCatch->Exception()); | 35 v8::String::Utf8Value exception(tryCatch->Exception()); |
36 const char* exceptionString = to_cstring(exception); | 36 const char* exceptionString = to_cstring(exception); |
37 Handle<Message> message = tryCatch->Message(); | 37 v8::Handle<v8::Message> message = tryCatch->Message(); |
38 if (message.IsEmpty()) { | 38 if (message.IsEmpty()) { |
39 // V8 didn't provide any extra information about this error; just | 39 // V8 didn't provide any extra information about this error; just |
40 // print the exception. | 40 // print the exception. |
41 fprintf(stderr, "%s\n", exceptionString); | 41 fprintf(stderr, "%s\n", exceptionString); |
42 } else { | 42 } else { |
43 // Print (filename):(line number): (message). | 43 // Print (filename):(line number): (message). |
44 String::Utf8Value filename(message->GetScriptOrigin().ResourceName()); | 44 v8::String::Utf8Value filename(message->GetScriptOrigin().ResourceName()
); |
45 const char* filenameString = to_cstring(filename); | 45 const char* filenameString = to_cstring(filename); |
46 int linenum = message->GetLineNumber(); | 46 int linenum = message->GetLineNumber(); |
47 fprintf(stderr, | 47 fprintf(stderr, |
48 "%s:%i: %s\n", filenameString, linenum, exceptionString); | 48 "%s:%i: %s\n", filenameString, linenum, exceptionString); |
49 // Print line of source code. | 49 // Print line of source code. |
50 String::Utf8Value sourceline(message->GetSourceLine()); | 50 v8::String::Utf8Value sourceline(message->GetSourceLine()); |
51 const char* sourceLineString = to_cstring(sourceline); | 51 const char* sourceLineString = to_cstring(sourceline); |
52 fprintf(stderr, "%s\n", sourceLineString); | 52 fprintf(stderr, "%s\n", sourceLineString); |
53 // Print wavy underline. | 53 // Print wavy underline. |
54 int start = message->GetStartColumn(); | 54 int start = message->GetStartColumn(); |
55 for (int i = 0; i < start; i++) { | 55 for (int i = 0; i < start; i++) { |
56 fprintf(stderr, " "); | 56 fprintf(stderr, " "); |
57 } | 57 } |
58 int end = message->GetEndColumn(); | 58 int end = message->GetEndColumn(); |
59 for (int i = start; i < end; i++) { | 59 for (int i = start; i < end; i++) { |
60 fprintf(stderr, "^"); | 60 fprintf(stderr, "^"); |
61 } | 61 } |
62 fprintf(stderr, "\n"); | 62 fprintf(stderr, "\n"); |
63 String::Utf8Value stackTrace(tryCatch->StackTrace()); | 63 v8::String::Utf8Value stackTrace(tryCatch->StackTrace()); |
64 if (stackTrace.length() > 0) { | 64 if (stackTrace.length() > 0) { |
65 const char* stackTraceString = to_cstring(stackTrace); | 65 const char* stackTraceString = to_cstring(stackTrace); |
66 fprintf(stderr, "%s\n", stackTraceString); | 66 fprintf(stderr, "%s\n", stackTraceString); |
67 } | 67 } |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 // The callback that implements the JavaScript 'inval' function. | 71 // The callback that implements the JavaScript 'inval' function. |
72 // Invalidates the current window, forcing a redraw. | 72 // Invalidates the current window, forcing a redraw. |
73 // | 73 // |
74 // JS: inval(); | 74 // JS: inval(); |
75 void Global::Inval(const v8::FunctionCallbackInfo<Value>& args) { | 75 void Global::Inval(const v8::FunctionCallbackInfo<v8::Value>& args) { |
76 gGlobal->getWindow()->inval(NULL); | 76 gGlobal->getWindow()->inval(NULL); |
77 } | 77 } |
78 | 78 |
79 // The callback that is invoked by v8 whenever the JavaScript 'print' | 79 // The callback that is invoked by v8 whenever the JavaScript 'print' |
80 // function is called. Prints its arguments on stdout separated by | 80 // function is called. Prints its arguments on stdout separated by |
81 // spaces and ending with a newline. | 81 // spaces and ending with a newline. |
82 // | 82 // |
83 // JS: print("foo", "bar"); | 83 // JS: print("foo", "bar"); |
84 void Global::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { | 84 void Global::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { |
85 bool first = true; | 85 bool first = true; |
86 HandleScope handleScope(args.GetIsolate()); | 86 v8::HandleScope handleScope(args.GetIsolate()); |
87 for (int i = 0; i < args.Length(); i++) { | 87 for (int i = 0; i < args.Length(); i++) { |
88 if (first) { | 88 if (first) { |
89 first = false; | 89 first = false; |
90 } else { | 90 } else { |
91 printf(" "); | 91 printf(" "); |
92 } | 92 } |
93 v8::String::Utf8Value str(args[i]); | 93 v8::String::Utf8Value str(args[i]); |
94 printf("%s", to_cstring(str)); | 94 printf("%s", to_cstring(str)); |
95 } | 95 } |
96 printf("\n"); | 96 printf("\n"); |
(...skipping 10 matching lines...) Expand all Loading... |
107 v8::String::NewFromUtf8( | 107 v8::String::NewFromUtf8( |
108 args.GetIsolate(), "Error: 2 arguments required.")); | 108 args.GetIsolate(), "Error: 2 arguments required.")); |
109 return; | 109 return; |
110 } | 110 } |
111 | 111 |
112 // Pull out the first arg, make sure it's a function. | 112 // Pull out the first arg, make sure it's a function. |
113 if (!args[0]->IsFunction()) { | 113 if (!args[0]->IsFunction()) { |
114 printf("Not a function passed to setTimeout.\n"); | 114 printf("Not a function passed to setTimeout.\n"); |
115 return; | 115 return; |
116 } | 116 } |
117 Handle<Function> timeoutFn = Handle<Function>::Cast(args[0]); | 117 v8::Handle<v8::Function> timeoutFn = v8::Handle<v8::Function>::Cast(args[0])
; |
118 | 118 |
119 double delay = args[1]->NumberValue(); | 119 double delay = args[1]->NumberValue(); |
120 int32_t id = gGlobal->getNextTimerID(); | 120 int32_t id = gGlobal->getNextTimerID(); |
121 | 121 |
122 gGlobal->fTimeouts[id].Reset(gGlobal->fIsolate, timeoutFn); | 122 gGlobal->fTimeouts[id].Reset(gGlobal->fIsolate, timeoutFn); |
123 | 123 |
124 // Create an SkEvent and add it with the right delay. | 124 // Create an SkEvent and add it with the right delay. |
125 SkEvent* evt = new SkEvent(); | 125 SkEvent* evt = new SkEvent(); |
126 evt->setTargetProc(Global::TimeOutProc); | 126 evt->setTargetProc(Global::TimeOutProc); |
127 evt->setFast32(id); | 127 evt->setFast32(id); |
128 evt->postDelay(delay); | 128 evt->postDelay(delay); |
129 | 129 |
130 args.GetReturnValue().Set(Integer::New(gGlobal->fIsolate, id)); | 130 args.GetReturnValue().Set(v8::Integer::New(gGlobal->fIsolate, id)); |
131 } | 131 } |
132 | 132 |
133 // Callback function for SkEvents used to implement timeouts. | 133 // Callback function for SkEvents used to implement timeouts. |
134 bool Global::TimeOutProc(const SkEvent& evt) { | 134 bool Global::TimeOutProc(const SkEvent& evt) { |
135 // Create a handle scope to keep the temporary object references. | 135 // Create a handle scope to keep the temporary object references. |
136 HandleScope handleScope(gGlobal->getIsolate()); | 136 v8::HandleScope handleScope(gGlobal->getIsolate()); |
137 | 137 |
138 // Create a local context from our global context. | 138 // Create a local context from our global context. |
139 Local<Context> context = gGlobal->getContext(); | 139 v8::Local<v8::Context> context = gGlobal->getContext(); |
140 | 140 |
141 // Enter the context so all the remaining operations take place there. | 141 // Enter the context so all the remaining operations take place there. |
142 Context::Scope contextScope(context); | 142 v8::Context::Scope contextScope(context); |
143 | 143 |
144 // Set up an exception handler before calling the Process function. | 144 // Set up an exception handler before calling the Process function. |
145 TryCatch tryCatch; | 145 v8::TryCatch tryCatch; |
146 | 146 |
147 int32_t id = evt.getFast32(); | 147 int32_t id = evt.getFast32(); |
148 if (gGlobal->fTimeouts.find(gGlobal->fLastTimerID) == gGlobal->fTimeouts.end
()) { | 148 if (gGlobal->fTimeouts.find(gGlobal->fLastTimerID) == gGlobal->fTimeouts.end
()) { |
149 printf("Not a valid timer ID.\n"); | 149 printf("Not a valid timer ID.\n"); |
150 return true; | 150 return true; |
151 } | 151 } |
152 | 152 |
153 const int argc = 0; | 153 const int argc = 0; |
154 Local<Function> onTimeout = | 154 v8::Local<v8::Function> onTimeout = |
155 Local<Function>::New(gGlobal->getIsolate(), gGlobal->fTimeouts[id]); | 155 v8::Local<v8::Function>::New(gGlobal->getIsolate(), gGlobal->fTimeou
ts[id]); |
156 Handle<Value> result = onTimeout->Call(context->Global(), argc, NULL); | 156 v8::Handle<v8::Value> result = onTimeout->Call(context->Global(), argc, NULL
); |
157 gGlobal->fTimeouts.erase(id); | 157 gGlobal->fTimeouts.erase(id); |
158 | 158 |
159 // Handle any exceptions or output. | 159 // Handle any exceptions or output. |
160 if (result.IsEmpty()) { | 160 if (result.IsEmpty()) { |
161 SkASSERT(tryCatch.HasCaught()); | 161 SkASSERT(tryCatch.HasCaught()); |
162 // Print errors that happened during execution. | 162 // Print errors that happened during execution. |
163 gGlobal->reportException(&tryCatch); | 163 gGlobal->reportException(&tryCatch); |
164 } else { | 164 } else { |
165 SkASSERT(!tryCatch.HasCaught()); | 165 SkASSERT(!tryCatch.HasCaught()); |
166 if (!result->IsUndefined()) { | 166 if (!result->IsUndefined()) { |
167 // If all went well and the result wasn't undefined then print the | 167 // If all went well and the result wasn't undefined then print the |
168 // returned value. | 168 // returned value. |
169 String::Utf8Value str(result); | 169 v8::String::Utf8Value str(result); |
170 const char* cstr = to_cstring(str); | 170 const char* cstr = to_cstring(str); |
171 printf("%s\n", cstr); | 171 printf("%s\n", cstr); |
172 } | 172 } |
173 } | 173 } |
174 return true; | 174 return true; |
175 } | 175 } |
176 | 176 |
177 // Creates a new execution environment containing the built-in functions. | 177 // Creates a new execution environment containing the built-in functions. |
178 Handle<Context> Global::createRootContext() { | 178 v8::Handle<v8::Context> Global::createRootContext() { |
179 // Create a template for the global object. | 179 // Create a template for the global object. |
180 Handle<ObjectTemplate> global = ObjectTemplate::New(); | 180 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); |
181 | 181 |
182 global->Set(v8::String::NewFromUtf8(fIsolate, "print"), | 182 global->Set(v8::String::NewFromUtf8(fIsolate, "print"), |
183 v8::FunctionTemplate::New(fIsolate, Global::Print)); | 183 v8::FunctionTemplate::New(fIsolate, Global::Print)); |
184 global->Set(v8::String::NewFromUtf8(fIsolate, "setTimeout"), | 184 global->Set(v8::String::NewFromUtf8(fIsolate, "setTimeout"), |
185 v8::FunctionTemplate::New(fIsolate, Global::SetTimeout)); | 185 v8::FunctionTemplate::New(fIsolate, Global::SetTimeout)); |
186 global->Set(v8::String::NewFromUtf8(fIsolate, "inval"), | 186 global->Set(v8::String::NewFromUtf8(fIsolate, "inval"), |
187 v8::FunctionTemplate::New(fIsolate, Global::Inval)); | 187 v8::FunctionTemplate::New(fIsolate, Global::Inval)); |
188 | 188 |
189 | 189 |
190 return Context::New(fIsolate, NULL, global); | 190 return v8::Context::New(fIsolate, NULL, global); |
191 } | 191 } |
192 | 192 |
193 void Global::initialize() { | 193 void Global::initialize() { |
194 // Create a stack-allocated handle scope. | 194 // Create a stack-allocated handle scope. |
195 HandleScope handleScope(fIsolate); | 195 v8::HandleScope handleScope(fIsolate); |
196 | 196 |
197 // Create a new context. | 197 // Create a new context. |
198 Handle<Context> context = this->createRootContext(); | 198 v8::Handle<v8::Context> context = this->createRootContext(); |
199 | 199 |
200 // Make the context persistent. | 200 // Make the context persistent. |
201 fContext.Reset(fIsolate, context); | 201 fContext.Reset(fIsolate, context); |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 // Creates the root context, parses the script into it, then stores the | 205 // Creates the root context, parses the script into it, then stores the |
206 // context in a global. | 206 // context in a global. |
207 // | 207 // |
208 // TODO(jcgregorio) Currently only handles one script. Need to move | 208 // TODO(jcgregorio) Currently only handles one script. Need to move |
209 // createRootContext to another call that's only done once. | 209 // createRootContext to another call that's only done once. |
210 bool Global::parseScript(const char script[]) { | 210 bool Global::parseScript(const char script[]) { |
211 | 211 |
212 // Create a stack-allocated handle scope. | 212 // Create a stack-allocated handle scope. |
213 HandleScope handleScope(fIsolate); | 213 v8::HandleScope handleScope(fIsolate); |
214 | 214 |
215 // Get the global context. | 215 // Get the global context. |
216 Handle<Context> context = this->getContext(); | 216 v8::Handle<v8::Context> context = this->getContext(); |
217 | 217 |
218 // Enter the scope so all operations take place in the scope. | 218 // Enter the scope so all operations take place in the scope. |
219 Context::Scope contextScope(context); | 219 v8::Context::Scope contextScope(context); |
220 | 220 |
221 v8::TryCatch tryCatch; | 221 v8::TryCatch tryCatch; |
222 | 222 |
223 // Compile the source code. | 223 // Compile the source code. |
224 Handle<String> source = String::NewFromUtf8(fIsolate, script); | 224 v8::Handle<v8::String> source = v8::String::NewFromUtf8(fIsolate, script); |
225 Handle<Script> compiledScript = Script::Compile(source); | 225 v8::Handle<v8::Script> compiledScript = v8::Script::Compile(source); |
226 | 226 |
227 if (compiledScript.IsEmpty()) { | 227 if (compiledScript.IsEmpty()) { |
228 // Print errors that happened during compilation. | 228 // Print errors that happened during compilation. |
229 this->reportException(&tryCatch); | 229 this->reportException(&tryCatch); |
230 return false; | 230 return false; |
231 } | 231 } |
232 | 232 |
233 // Try running it now to create the onDraw function. | 233 // Try running it now to create the onDraw function. |
234 Handle<Value> result = compiledScript->Run(); | 234 v8::Handle<v8::Value> result = compiledScript->Run(); |
235 | 235 |
236 // Handle any exceptions or output. | 236 // Handle any exceptions or output. |
237 if (result.IsEmpty()) { | 237 if (result.IsEmpty()) { |
238 SkASSERT(tryCatch.HasCaught()); | 238 SkASSERT(tryCatch.HasCaught()); |
239 // Print errors that happened during execution. | 239 // Print errors that happened during execution. |
240 this->reportException(&tryCatch); | 240 this->reportException(&tryCatch); |
241 return false; | 241 return false; |
242 } | 242 } |
243 | 243 |
244 return true; | 244 return true; |
245 } | 245 } |
OLD | NEW |