| 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 |