Commit 958b3bf4 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Parsing of basic module declarations (no imports/exports yet).

Module definitions are not compiled or otherwise executed yet.
Toplevel module identifiers are bound but never initialized.

R=kmillikin@chromium.org,mstarzinger@google.com
BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9401008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10759 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1336b913
...@@ -548,17 +548,17 @@ class ModuleVariable: public Module { ...@@ -548,17 +548,17 @@ class ModuleVariable: public Module {
public: public:
DECLARE_NODE_TYPE(ModuleVariable) DECLARE_NODE_TYPE(ModuleVariable)
Variable* var() const { return var_; } VariableProxy* proxy() const { return proxy_; }
protected: protected:
template<class> friend class AstNodeFactory; template<class> friend class AstNodeFactory;
explicit ModuleVariable(Variable* var) explicit ModuleVariable(VariableProxy* proxy)
: var_(var) { : proxy_(proxy) {
} }
private: private:
Variable* var_; VariableProxy* proxy_;
}; };
...@@ -2536,19 +2536,19 @@ class AstNodeFactory BASE_EMBEDDED { ...@@ -2536,19 +2536,19 @@ class AstNodeFactory BASE_EMBEDDED {
VISIT_AND_RETURN(ModuleLiteral, module) VISIT_AND_RETURN(ModuleLiteral, module)
} }
ModuleVariable* NewModuleVariable(Variable* var) { ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
ModuleVariable* module = new(zone_) ModuleVariable(var); ModuleVariable* module = new(zone_) ModuleVariable(proxy);
VISIT_AND_RETURN(ModuleLiteral, module) VISIT_AND_RETURN(ModuleVariable, module)
} }
ModulePath* NewModulePath(Module* origin, Handle<String> name) { ModulePath* NewModulePath(Module* origin, Handle<String> name) {
ModulePath* module = new(zone_) ModulePath(origin, name); ModulePath* module = new(zone_) ModulePath(origin, name);
VISIT_AND_RETURN(ModuleLiteral, module) VISIT_AND_RETURN(ModulePath, module)
} }
ModuleUrl* NewModuleUrl(Handle<String> url) { ModuleUrl* NewModuleUrl(Handle<String> url) {
ModuleUrl* module = new(zone_) ModuleUrl(url); ModuleUrl* module = new(zone_) ModuleUrl(url);
VISIT_AND_RETURN(ModuleLiteral, module) VISIT_AND_RETURN(ModuleUrl, module)
} }
Block* NewBlock(ZoneStringList* labels, Block* NewBlock(ZoneStringList* labels,
......
...@@ -356,6 +356,10 @@ class Context: public FixedArray { ...@@ -356,6 +356,10 @@ class Context: public FixedArray {
Map* map = this->map(); Map* map = this->map();
return map == map->GetHeap()->block_context_map(); return map == map->GetHeap()->block_context_map();
} }
bool IsModuleContext() {
Map* map = this->map();
return map == map->GetHeap()->module_context_map();
}
// Tells whether the global context is marked with out of memory. // Tells whether the global context is marked with out of memory.
inline bool has_out_of_memory(); inline bool has_out_of_memory();
......
...@@ -111,7 +111,8 @@ DEFINE_bool(use_strict, false, "enforce strict mode") ...@@ -111,7 +111,8 @@ DEFINE_bool(use_strict, false, "enforce strict mode")
DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof") DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof")
DEFINE_bool(harmony_scoping, false, "enable harmony block scoping") DEFINE_bool(harmony_scoping, false, "enable harmony block scoping")
DEFINE_bool(harmony_modules, false, "enable harmony modules") DEFINE_bool(harmony_modules, false,
"enable harmony modules (implies block scoping)")
DEFINE_bool(harmony_proxies, false, "enable harmony proxies") DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
DEFINE_bool(harmony_collections, false, DEFINE_bool(harmony_collections, false,
"enable harmony collections (sets, maps, and weak maps)") "enable harmony collections (sets, maps, and weak maps)")
...@@ -120,6 +121,7 @@ DEFINE_implication(harmony, harmony_scoping) ...@@ -120,6 +121,7 @@ DEFINE_implication(harmony, harmony_scoping)
DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_modules)
DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_proxies)
DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony, harmony_collections)
DEFINE_implication(harmony_modules, harmony_scoping)
// Flags for experimental implementation features. // Flags for experimental implementation features.
DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values") DEFINE_bool(smi_only_arrays, true, "tracks arrays with only smi values")
......
...@@ -2230,6 +2230,12 @@ bool Heap::CreateInitialMaps() { ...@@ -2230,6 +2230,12 @@ bool Heap::CreateInitialMaps() {
} }
set_block_context_map(Map::cast(obj)); set_block_context_map(Map::cast(obj));
{ MaybeObject* maybe_obj =
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_module_context_map(Map::cast(obj));
{ MaybeObject* maybe_obj = { MaybeObject* maybe_obj =
AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false; if (!maybe_obj->ToObject(&obj)) return false;
......
...@@ -130,6 +130,7 @@ namespace internal { ...@@ -130,6 +130,7 @@ namespace internal {
V(Map, catch_context_map, CatchContextMap) \ V(Map, catch_context_map, CatchContextMap) \
V(Map, with_context_map, WithContextMap) \ V(Map, with_context_map, WithContextMap) \
V(Map, block_context_map, BlockContextMap) \ V(Map, block_context_map, BlockContextMap) \
V(Map, module_context_map, ModuleContextMap) \
V(Map, oddball_map, OddballMap) \ V(Map, oddball_map, OddballMap) \
V(Map, message_object_map, JSMessageObjectMap) \ V(Map, message_object_map, JSMessageObjectMap) \
V(Map, foreign_map, ForeignMap) \ V(Map, foreign_map, ForeignMap) \
......
This diff is collapsed.
...@@ -464,7 +464,8 @@ class Parser { ...@@ -464,7 +464,8 @@ class Parser {
}; };
enum VariableDeclarationContext { enum VariableDeclarationContext {
kSourceElement, kModuleElement,
kBlockElement,
kStatement, kStatement,
kForStatement kForStatement
}; };
...@@ -575,7 +576,16 @@ class Parser { ...@@ -575,7 +576,16 @@ class Parser {
// for failure at the call sites. // for failure at the call sites.
void* ParseSourceElements(ZoneList<Statement*>* processor, void* ParseSourceElements(ZoneList<Statement*>* processor,
int end_token, bool* ok); int end_token, bool* ok);
Statement* ParseSourceElement(ZoneStringList* labels, bool* ok); Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
Block* ParseModuleDeclaration(bool* ok);
Module* ParseModule(bool* ok);
Module* ParseModuleLiteral(bool* ok);
Module* ParseModulePath(bool* ok);
Module* ParseModuleVariable(bool* ok);
Module* ParseModuleUrl(bool* ok);
Block* ParseImportDeclaration(bool* ok);
Block* ParseExportDeclaration(bool* ok);
Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
Statement* ParseStatement(ZoneStringList* labels, bool* ok); Statement* ParseStatement(ZoneStringList* labels, bool* ok);
Statement* ParseFunctionDeclaration(bool* ok); Statement* ParseFunctionDeclaration(bool* ok);
Statement* ParseNativeDeclaration(bool* ok); Statement* ParseNativeDeclaration(bool* ok);
......
...@@ -84,7 +84,7 @@ void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) { ...@@ -84,7 +84,7 @@ void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) { void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
PrintLiteral(node->var()->name(), false); Visit(node->proxy());
} }
...@@ -773,7 +773,7 @@ void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) { ...@@ -773,7 +773,7 @@ void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
void AstPrinter::VisitModuleVariable(ModuleVariable* node) { void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
PrintLiteralIndented("VARIABLE", node->var()->name(), false); Visit(node->proxy());
} }
......
...@@ -11283,6 +11283,29 @@ static Handle<JSObject> MaterializeBlockScope( ...@@ -11283,6 +11283,29 @@ static Handle<JSObject> MaterializeBlockScope(
} }
// Create a plain JSObject which materializes the module scope for the specified
// module context.
static Handle<JSObject> MaterializeModuleScope(
Isolate* isolate,
Handle<Context> context) {
ASSERT(context->IsModuleContext());
Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
// Allocate and initialize a JSObject with all the members of the debugged
// module.
Handle<JSObject> module_scope =
isolate->factory()->NewJSObject(isolate->object_function());
// Fill all context locals.
if (!CopyContextLocalsToScopeObject(
isolate, scope_info, context, module_scope)) {
return Handle<JSObject>();
}
return module_scope;
}
// Iterate over the actual scopes visible from a stack frame. The iteration // Iterate over the actual scopes visible from a stack frame. The iteration
// proceeds from the innermost visible nested scope outwards. All scopes are // proceeds from the innermost visible nested scope outwards. All scopes are
// backed by an actual context except the local scope, which is inserted // backed by an actual context except the local scope, which is inserted
...@@ -11295,7 +11318,8 @@ class ScopeIterator { ...@@ -11295,7 +11318,8 @@ class ScopeIterator {
ScopeTypeWith, ScopeTypeWith,
ScopeTypeClosure, ScopeTypeClosure,
ScopeTypeCatch, ScopeTypeCatch,
ScopeTypeBlock ScopeTypeBlock,
ScopeTypeModule
}; };
ScopeIterator(Isolate* isolate, ScopeIterator(Isolate* isolate,
...@@ -11418,6 +11442,9 @@ class ScopeIterator { ...@@ -11418,6 +11442,9 @@ class ScopeIterator {
ASSERT(context_->IsFunctionContext() || ASSERT(context_->IsFunctionContext() ||
!scope_info->HasContext()); !scope_info->HasContext());
return ScopeTypeLocal; return ScopeTypeLocal;
case MODULE_SCOPE:
ASSERT(context_->IsModuleContext());
return ScopeTypeModule;
case GLOBAL_SCOPE: case GLOBAL_SCOPE:
ASSERT(context_->IsGlobalContext()); ASSERT(context_->IsGlobalContext());
return ScopeTypeGlobal; return ScopeTypeGlobal;
...@@ -11448,6 +11475,9 @@ class ScopeIterator { ...@@ -11448,6 +11475,9 @@ class ScopeIterator {
if (context_->IsBlockContext()) { if (context_->IsBlockContext()) {
return ScopeTypeBlock; return ScopeTypeBlock;
} }
if (context_->IsModuleContext()) {
return ScopeTypeModule;
}
ASSERT(context_->IsWithContext()); ASSERT(context_->IsWithContext());
return ScopeTypeWith; return ScopeTypeWith;
} }
...@@ -11471,6 +11501,8 @@ class ScopeIterator { ...@@ -11471,6 +11501,8 @@ class ScopeIterator {
return MaterializeClosure(isolate_, CurrentContext()); return MaterializeClosure(isolate_, CurrentContext());
case ScopeIterator::ScopeTypeBlock: case ScopeIterator::ScopeTypeBlock:
return MaterializeBlockScope(isolate_, CurrentContext()); return MaterializeBlockScope(isolate_, CurrentContext());
case ScopeIterator::ScopeTypeModule:
return MaterializeModuleScope(isolate_, CurrentContext());
} }
UNREACHABLE(); UNREACHABLE();
return Handle<JSObject>(); return Handle<JSObject>();
......
...@@ -704,6 +704,7 @@ static const char* Header(ScopeType type) { ...@@ -704,6 +704,7 @@ static const char* Header(ScopeType type) {
switch (type) { switch (type) {
case EVAL_SCOPE: return "eval"; case EVAL_SCOPE: return "eval";
case FUNCTION_SCOPE: return "function"; case FUNCTION_SCOPE: return "function";
case MODULE_SCOPE: return "module";
case GLOBAL_SCOPE: return "global"; case GLOBAL_SCOPE: return "global";
case CATCH_SCOPE: return "catch"; case CATCH_SCOPE: return "catch";
case BLOCK_SCOPE: return "block"; case BLOCK_SCOPE: return "block";
......
...@@ -263,6 +263,7 @@ class Scope: public ZoneObject { ...@@ -263,6 +263,7 @@ class Scope: public ZoneObject {
// Specific scope types. // Specific scope types.
bool is_eval_scope() const { return type_ == EVAL_SCOPE; } bool is_eval_scope() const { return type_ == EVAL_SCOPE; }
bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
bool is_module_scope() const { return type_ == MODULE_SCOPE; }
bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
bool is_catch_scope() const { return type_ == CATCH_SCOPE; } bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
bool is_block_scope() const { return type_ == BLOCK_SCOPE; } bool is_block_scope() const { return type_ == BLOCK_SCOPE; }
......
...@@ -461,6 +461,7 @@ enum CallKind { ...@@ -461,6 +461,7 @@ enum CallKind {
enum ScopeType { enum ScopeType {
EVAL_SCOPE, // The top-level scope for an eval source. EVAL_SCOPE, // The top-level scope for an eval source.
FUNCTION_SCOPE, // The top-level scope for a function. FUNCTION_SCOPE, // The top-level scope for a function.
MODULE_SCOPE, // The scope introduced by a module literal
GLOBAL_SCOPE, // The top-level scope for a program or a top-level eval. GLOBAL_SCOPE, // The top-level scope for a program or a top-level eval.
CATCH_SCOPE, // The scope introduced by catch. CATCH_SCOPE, // The scope introduced by catch.
BLOCK_SCOPE, // The scope introduced by a new block. BLOCK_SCOPE, // The scope introduced by a new block.
......
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --harmony-modules
// Test basic module syntax, with and without ASI.
module A {}
module A1 = A
module A2 = A;
module A3 = A2
module B {
var x
var x, y;
var x = 0, y
let x, y
let z = 1
const c = 9
function f() {}
module C {
let x
module D {}
let y
}
let zz = ""
}
module C1 = B.C;
module D1 = B.C.D
module D2 = C1.D
module D3 = D2
module E1 at "http://where"
module E2 at "http://where";
module E3 = E1.F
// Check that ASI does not interfere.
module
X
{
let x
}
module
Y
=
X
module
Z
at
"file://local"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment